shared_ptr
アプローチはかなり一般的です。ただし、 にshared_ptr
追加の引数としてa を渡す代わりに、 の代わりにインスタンス オブジェクトとして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();
このスニペットではfoo.get()
、foo->shared_from_this()
両方が同じインスタンスを指しています。これにより、特定が困難なメモリ リークを防ぐことができます。たとえば、元のサンプル コードでは、を呼び出そうとすると、 Protocol::AsyncReadMessage
ifの copy-constructor throws でメモリ リークが発生します。Boost.Asio の非同期 TCP デイタイム サーバーと多くの例は、Boost.Asio 内で使用されていることを示しています。理解を深めるために、この質問では特に非同期の Boost.Asio 関数と.AsyncReadHandler
AsyncReadMessage
enable_shared_from_this
shared_ptr
Protocol::AsyncHelper
また、元のコードでは、テンプレート メンバー関数を持つ非テンプレート クラスにするよりも、テンプレート クラスを作成する方が簡単な場合があります。これにより、AsyncHelper
はプロトコル、ストリーム、およびハンドラーをコンストラクター引数として受け入れ、それらをメンバー変数として格納できます。さらに、bind
渡す必要がある引数の量が減り、メンバー関数がテンプレートでなくなるため、完全な型を指定する必要がないため、呼び出しが少し読みやすくなります。 ここに例の簡単なパスがあります。