提升shared_from_this<>()

时间:2010-09-02 17:23:37

标签: c++ boost boost-asio boost-bind

有人可以用一些简洁的词汇总结一下如何使用boost shared_from_this<>()智能指针,特别是从使用bind函数在io_service中注册处理程序的角度来看。

编辑:有些回复要求更多背景信息。基本上,我正在寻找“陷阱”,人们使用这种机制观察到的反直觉行为。

5 个答案:

答案 0 :(得分:31)

我遇到的最大“陷阱”是从构造函数中调用shared_from_this是非法的。这直接遵循以下规则:在调用shared_from_this之前,必须存在对象的shared_ptr。

答案 1 :(得分:14)

根据我的理解,有时在你的代码中你希望一个类为自己提供shared_ptr,以便代码的其他部分可以在构造之后获得类的对象的shared_ptr。 / p>

问题在于,如果你的类只有shared_ptr<>作为成员变量,它将永远不会自动被破坏,因为总有“最后一个引用”挂在自身上。继承自enable_shared_from_this会为您的类提供一个自动方法,该方法不仅返回shared_ptr,而且仅将弱共享指针保存为成员变量,以免影响引用计数。这样,当最后一次引用它时,你的类将像往常一样被释放。

我从未使用它,但这是我对其工作原理的理解。

答案 2 :(得分:8)

如果对象想要访问指向自身的shared_from_this<>,则使用

shared_ptr<>

通常,对象只知道隐式this指针,但不知道管理它的任何shared_ptr<>。此外,this无法轻松转换为与其他现有shared_ptr<>实例共享所有权的shared_ptr<>,因此对象无法轻松获得有效shared_ptr<>到本身。

shared_from_this<>可用于解决此问题。例如:

struct A : boost::enable_shared_from_this<A> {
   server *io;
   // ...

   void register_self() {
      io->add_client(shared_from_this());
   }
};

答案 3 :(得分:5)

boost::asio::io_service destructor文档很好地解释了

  

描述的破坏序列   以上允许程序简化   他们的资源管理使用   的shared_ptr&LT;取代。对象的位置   寿命与a的寿命有关   连接(或其他一些序列)   异步操作),一个shared_ptr   将对象绑定到   所有异步处理程序   与之相关的操作。这个   工作原理如下:

     
      
  • 当单个连接结束时,所有关联的异步操作   完成。相应的处理程序   对象被摧毁,所有   shared_ptr对象的引用   被毁了。
  •   
  • 要关闭整个程序,调用io_service函数stop()   尽快终止任何run()调用   尽可能。 io_service析构函数   以上定义会破坏所有处理程序,   导致所有shared_ptr引用   所有连接对象   破坏。
  •   

通常,您的对象将链接异步操作,其中处理程序使用boost::bindboost::shared_from_this()绑定到成员函数。有一些examples使用了这个概念。

答案 4 :(得分:1)

上面的某些评论中缺少内容。这是一个对我有帮助的例子:

Boost enable_shared_from_this example

对我来说,我一直在为错误的弱指针而苦苦挣扎。您必须以shared_ptr方式分配对象:

class SyncSocket: public boost::enable_shared_from_this<SyncSocket>

并分配一个这样的东西:

boost::shared_ptr<SyncSocket> socket(new SyncSocket);

然后您可以执行以下操作:

socket->connect(...);

许多示例向您展示了如何使用shared_from_this()这样的东西:

boost::asio::async_read_until(socket, receiveBuffer, haveData,
        boost::bind(&SyncSocket::dataReceived, shared_from_this(), boost::asio::placeholders::error));

但是对我来说缺少的是使用shared_ptr来分配对象。