shared_ptr 方法相当普遍。但是,可以将shared_ptr 作为实例对象传递给bind,而不是将shared_ptr 作为附加参数传递给this。
boost::shared_ptr< my_class > ptr( this );
boost::asio::async_read( stream, buffer,
boost::bind( &my_class::read_handler, ptr,
boost::asio::placeholders::error
boost::asio::placeholders::bytes_transferred ) );
通常,由于实例将通过shared_ptr 进行管理,它可能在也可能不在this 的上下文中,所以最好使用Boost.SmartPointer 的enable_shared_from_this。当一个类从boost::enable_shared_from_this继承时,它提供了一个shared_from_this()成员函数,该函数将一个有效的shared_ptr实例返回给this。
class my_class: public boost::enable_shared_from_this< my_class >
{
void read()
{
boost::asio::async_read( stream, buffer,
boost::bind( &my_class::read_handler, shared_from_this(),
boost::asio::placeholders::error
boost::asio::placeholders::bytes_transferred ) );
}
};
boost::shared_ptr< my_class > foo( new my_class() );
foo->read();
在这个 sn-p 中,foo.get() 和 foo->shared_from_this() 都指向同一个实例。这有助于防止难以定位的内存泄漏。例如,在原始示例代码中,如果AsyncReadHandler 的复制构造函数在尝试调用AsyncReadMessage 时抛出,则会在Protocol::AsyncReadMessage 中发生内存泄漏。 Boost.Asio 的asynchronous TCP daytime server 和许多examples 显示enable_shared_from_this 在Boost.Asio 中使用。为了更深入的了解,this 问题专门涵盖了异步 Boost.Asio 函数和shared_ptr。
另外,在原始代码中,将Protocol::AsyncHelper 设为模板类可能比将其设为具有模板成员函数的非模板类更容易。这将允许AsyncHelper 接受协议、流和处理程序作为构造函数参数,并将它们存储为成员变量。此外,它使bind 调用更易于阅读,因为它减少了需要传递的参数数量,并且由于成员函数不再是模板,因此无需指定它们的完整类型。 Here 是一个示例。