2011-12-14 15 views
3

私はクラスからデストラクタでshared_from_thisを呼び出すことが許可されていないことが判明:ブーストshared_from_thisとデストラクタ

https://svn.boost.org/trac/boost/ticket/147

この動作は仕様です。デストラクタはオブジェクトを破壊するので、デストラクタが終了すると束縛されるので、shared_ptrを作成するのは安全ではありません。

私は引数を理解していますが、参照をクリーンアップするための "shared_from_this"ポインタが必要な場合はどうなりますか?ここで

class A{ 
public: 
    A(Manager * m) : m_(m) { 
     m_->add(this); 
    } 

    ~A() { 
     m_->remove(this); 
    } 

private: 
    Manager * m_; 
}; 

私は共有ポインタに翻訳しようとしています。ここ

は、私はshared_ptrのを使用していない例です。しかし、私はデストラクタを完了するための良い方法を見つけることができません。

class A : public boost::enable_shared_from_this<A> { 
public: 
    typedef boost::shared_ptr<A> Ptr; 

    static Ptr create(Manager * m) { 
     Ptr p(new A(m)); 
     p->init(); 
     return p; 
    } 

    ~A() { 
     // NON-WORKING 
     // m_->remove(shared_from_this()); 
    } 

private: 
    A(Manager * m) : m_(m) { } 

    void init() { 
     m_->add(shared_from_this()); 
    } 

    Manager * m_; 
}; 

どのように私は、上記の例でデストラクタを実装することができますか?

+0

私は新しいタグを作成したい:weak-ptr-of-enabled-of-this-from-this – curiousguy

答えて

4

あなたのマネージャにあなたのオブジェクトにshared_ptrがある場合、それはそれを所有しています。 したがって、あなたのオブジェクトは破壊されてはいけません。マネージャーはまだそのオブジェクトへの参照を持っています。

弱いポインタをマネージャに渡すことができますが、ポインタがまだ有効であることをマネージャが確認し、そうでない場合は削除します。

あなたの質問は面白いですが、あなたのケースは誤解によって引き起こされます。オブジェクトがあなたのオブジェクトへの参照を所有している限り、それは破壊されないshared_ptrの目的です。デストラクタを呼び出すには、手動でポインタの削除を呼び出す必要があります。これは、shared_ptrを操作するときの悪い動作です。

シンプルは誰が本当にオブジェクトを所有しているかを定義し、それらにshared_ptrを与えます。一部のコードでオブジェクトが必要になることがある場合(存在する場合)、weak_ptrを与えます。

3

Managerインスタンスにクラスのshared_ptrがある場合、そのshared_ptrがなくなるまで、クラスは破棄されません。したがって、Managerが実際にインスタンスにweak_ptrを格納していると仮定します。その場合、ManagerのAPIはおそらく、デストラクタで取得できるはずのweak_ptrを受け入れるべきです。できない場合は、コンストラクタ内に作成し、後で保存してください。

+0

weak_ptrは、オブジェクトを破棄させるためのものです。そのため、weak_ptrの有効性を確認するのはオブジェクトにあります。 しかし、とにかく良い解決策。 – Geoffroy

+0

あなたが誤解している問題であると指摘したことのいくつかの選択肢を提示しようとしました。私たちは、shared_ptrを保持しているものから自分たちのデストラクタに自分自身を登録解除するという状況にあってはいけません。 –

+2

こんにちは。 "デストラクタで取得できるはずのweak_ptr" ---説明してください。デストラクタでweak_ptrを取得するにはどうしたらいいですか? 'enable_shared_from_this'には' weak_from_this'ではなく 'shared_from_this'だけが含まれています... –

1

ここで私はそれを共有ポインタに変換しようとしました。

Do not。

あなたのファーストクラスは、暗黙的に宣言されたコピーコンストラクタとコピー代入であり、生ポインタの使用とは無関係です。

なぜスマートポインタを使用するのですか?それはファッショナブルなので?

weak_ptrは、ポインタのようなクラスとして誤解されることがよくあります(弱い参照物です)。

weak_ptrはまれです。(Boostのドキュメントでも、weak_ptrが適切なときに混乱が広がります)

enable_shared_from_thisさらに誤解を招きます。

関連する問題