【问题标题】:Will a boost smart pointer help me?提升智能指针对我有帮助吗?
【发布时间】:2010-07-09 12:51:13
【问题描述】:

我正在使用 Xerces 编写一些 xml。

这是从我的代码中提取的几行代码:

DOMLSSerializer *serializer = ((DOMImplementationLS*)implementation)->createLSSerializer();
serializer->release();

是否有我可以使用的 boost 智能指针,所以我可以避免调用 serializer->release();因为它不是异常安全的。我看到的问题是智能指针只能在您的指针对象上调用 delete,是否可以将其自定义为调用 release?

谢谢

【问题讨论】:

  • 如果您不想调用 release,因为它现在是异常安全的,如果您希望它自己调用 release,智能指针将如何提供帮助?
  • 对不起,我的意思是它不会像我上面说明的那样保存调用 release(),因为当抛出异常时它可能不会被调用。

标签: c++ boost


【解决方案1】:

是的,智能指针可以调用自定义的“删除”函数对象。

#include <iostream>
#include <tr1/memory>
struct Example {
    void release() { std::cout << "Example::release() called\n"; }
};
struct ExampleDeleter {
        void operator()(Example* e) { e->release(); }
};
int main()
{
        {
        std::tr1::shared_ptr<Example> p ( new Example, ExampleDeleter() );
        }
        std::cout << " see?\n";
}

(对于 boost 相同:参见 shared_ptr(Y * p, D d); 构造函数。)

【讨论】:

  • @Greg Domjan 对mem_fun 的回答实际上更适合这种简单的情况。
【解决方案2】:

是的,boost::shared_ptr 可以与自定义删除函数(如 Cubbi 所示)或删除函数一起使用:

void my_deleter(DOMLSSerializer* s) {
    s->release();
}

// ...
boost::shared_ptr<DOMLSSerializer> serializer(foo->createLSSerializer(), my_deleter);

【讨论】:

    【解决方案3】:

    不知道为什么人们不再用这种方式编写自己的包装器了@Cubbi

    回复make shared ptr not use delete

    shared_ptr<DOMLSSerializer> serializer( 
      ((DOMImplementationLS*)implementation)->createLSSerializer(), 
      std::mem_fun(&DOMLSSerializer::release) );
    

    【讨论】:

    • 你是对的,但它不是std::mem_fun,因为它会被指针调用吗?在我的示例中,shared_ptr&lt;Example&gt; p (new Example, std::mem_fun(&amp;Example::release)); 有效,...mem_fun_ref... 无法编译。
    【解决方案4】:

    如果您只需要一个很小的 ​​RAII 类,那么您可以自己编写帮助程序类。它太小了,几乎不能承受自己的重量(更不用说拉图书馆了):

    class DOMLSSerializerOwner {
    public:
      DOMLSSSerializerOwner( DOMLSSerializer *serializer ) : m_serializer( serializer ) { }
      ~DOMLSSerializerOwner() { m_serializer->release(); }
    
      operator DOMLSSerializer*() { return m_serializer; }
    
    private:
      DOMLSSerializerOwner( const DOMLSSerializerOwner &other ); // disabled
      void operator=( const DOMLSSerializerOwner &rhs ); // disabled
    
      DOMLSSerializer *m_serializer;
    };
    

    然后你可以让你的代码读取:

    void f()
    {
      DOMLSSerializerOwner serializer = ((DOMImplementationLS*)implementation)->createLSSerializer();
      serializer->doThis();
      serializer->doThis();
      // Look Ma: no release() call; 'serializer' does it automatically when going out of scope
    }
    

    【讨论】:

    • operator T* 是不够的,你至少需要operator-&gt;。此外,隐式转换并不总是受欢迎的,指针值的显式 getter 更好。
    猜你喜欢
    • 2011-02-01
    • 1970-01-01
    • 2019-01-27
    • 1970-01-01
    • 2013-04-16
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多