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