shared_from_this<>()
特にbind関数を使用してio_serviceにハンドラーを登録するという観点から、ブーストスマートポインターの使用方法を簡潔に要約できますか。
編集:いくつかの回答は、より多くの文脈を求めています。基本的に、私は「落とし穴」を探しています。これは、このメカニズムを使用して人々が観察した直感に反する動作です。
shared_from_this<>()
特にbind関数を使用してio_serviceにハンドラーを登録するという観点から、ブーストスマートポインターの使用方法を簡潔に要約できますか。
編集:いくつかの回答は、より多くの文脈を求めています。基本的に、私は「落とし穴」を探しています。これは、このメカニズムを使用して人々が観察した直感に反する動作です。
私が遭遇した最大の「落とし穴」は、コンストラクターからshared_from_thisを呼び出すことは違法であるということです。これは、shared_from_thisを呼び出す前に、オブジェクトへのshared_ptrが存在する必要があるというルールに直接準拠しています。
私の理解では、コード内でクラスがshared_ptr
それ自体に'を提供して、コードの他の部分が構築後にクラスのオブジェクトに対してshared_ptrを取得できるようにしたい場合があります。
問題は、クラスがshared_ptr<>
メンバー変数としてそれ自体を持っているだけの場合、それ自体にぶら下がっている「最後の参照」が常にあるため、自動的に破棄されることはないということです。fromを継承するとenable_shared_from_this
、クラスに自動メソッドが与えられます。このメソッドは、を返すだけでなくshared_ptr
、参照カウントに影響を与えないように、弱い共有ポインターをメンバー変数として保持するだけです。このようにして、クラスへの最後の参照がなくなると、通常どおりクラスが解放されます。
私はそれを使ったことがありませんが、これはそれがどのように機能するかについての私の理解です。
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());
}
};
boost::asio::io_service
デストラクタのドキュメントはそれをかなりよく説明しています
上記の破棄シーケンスにより、プログラムはshared_ptr<>を使用してリソース管理を簡素化できます。オブジェクトの有効期間が接続の有効期間(またはその他の非同期操作のシーケンス)に関連付けられている場合、オブジェクトへのshared_ptrは、それに関連付けられているすべての非同期操作のハンドラーにバインドされます。これは次のように機能します。
- 単一の接続が終了すると、関連するすべての非同期操作が完了します。対応するハンドラオブジェクトが破棄され、オブジェクトへのすべてのshared_ptr参照が破棄されます。
- プログラム全体をシャットダウンするには、io_service関数stop()を呼び出して、run()呼び出しをできるだけ早く終了します。上記で定義されたio_serviceデストラクタは、すべてのハンドラを破棄し、すべての接続オブジェクトへのすべてのshared_ptr参照を破棄します。
通常、オブジェクトは、ハンドラーがとを使用してメンバー関数にバインドされる非同期操作をチェーンしboost::bind
ますboost::shared_from_this()
。この概念を使用するいくつかの例があります。
上記のコメントの一部に欠けているものがあります。これが私を助けた例です:
enable_shared_from_thisの例をブーストする
私にとって、私は悪い弱いポインタに関するエラーに苦労していました。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を使用していたので、私には欠けていました。