有人可以用一些简洁的词汇总结一下如何使用boost shared_from_this<>()
智能指针,特别是从使用bind函数在io_service中注册处理程序的角度来看。
编辑:有些回复要求更多背景信息。基本上,我正在寻找“陷阱”,人们使用这种机制观察到的反直觉行为。
答案 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::bind
和boost::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来分配对象。