3

次のケースを検討してください。

typedef boost::shared_ptr<B> BPtr;

class A
{
public:
    A() { b_ptr = BPtr(new B); }
    void a_func() { C::c_func(b_ptr); }
private:
    BPtr b_ptr;
}

class B
{
public:
    B() { b_ptr = BPtr(this); }
    void b_func() { C::c_func(b_ptr); }
private:
    BPtr b_ptr;
}

class C
{
public:
    static void c_func(BPtr b_ptr) { /*...*/ }
}

で shared_ptr をインスタンス化してもthisよろしいですか?
2 つの shared_ptr オブジェクトが同じオブジェクトを指していても問題ありませんか? (例: A::b_ptr と B::b_ptr)
これら 2 つのうちの 1 つが範囲外になった場合、B のインスタンスは削除されますか?

私は何か根本的に間違ったことをしていると思います。
B のコンストラクターに b_ptr の依存性注入を使用することも考えましたが、それも非常に間違っているようです。

更新:
明確にするために - A と B の両方が C::c_func を使用する必要があります。次に、いくつかの処理の後、C は、上記で指定していない B のコールバック関数を呼び出す必要があります。実際、興味深いのは次の 2 つのケースです。

  1. C がステートフルではないという要件がある場合、上記のコードのように、A と B の両方から BPtr を受け取る必要があります。
  2. C がステートフルで、A と B の両方が個別の C インスタンスをインスタンス化し、C の ctor に BPtr を与える場合。
4

2 に答える 2

10

これで shared_ptr をインスタンス化してもよろしいですか?

いいえ、少なくともいくつかの理由で:

  1. AまたはBオブジェクトをスタック上または静的に作成shared_ptrすると、スタック上に作成されたオブジェクトを「所有」することになります。オブジェクトがshared_ptr破棄されると、デストラクタが呼び出さdeleteれ、オブジェクトが呼び出され、悪いことだけが起こります。さらに、オブジェクトが動的に作成されたとしても、クラスの所有者がそれをどうするかはわかりませんauto_ptr。完全に異なるセマンティクスを持つ のような他のタイプのスマート ポインターに割り当てる可能性があります。

  2. 循環参照になってしまいます。たとえば、メンバーであるオブジェクトをb_ptr所有しています。オブジェクトを破棄するにBは、手動で行う必要があります。.reset()B

を使用してshared_ptrfromを取得できますが、多くの注意点があります。つまり、コンストラクターを呼び出すことはできません。それでも、オブジェクト自体の内部にオブジェクトを格納したくありません。意味がありません。thisenable_shared_from_thisenable_shared_from_thisshared_ptr

私は何か根本的に間違ったことをしていると思います。

はい、しかし、正確に何をしようとしているのかを言っていないので、代わりに何をすべきかを言うのは難しい. そもそも何をしようとしているのかではなく、これをどのようにしようとしているのかを私たちに伝えただけです。

于 2011-01-22T00:22:19.623 に答える
0

std::enable_shared_from_this を使用するように再設計することをお勧めします。

class B
{
   B();
public:
   std::shared_ptr<B> create() { return std::make_shared<B>(); } // Make sure B is allocated as shared_ptr inorder to ensure that shared_from_this() works.
};

ただし、それが API の問題である場合は、次のことを行うことができます (ただし、お勧めしません)。

void b_func() { C::c_func(BPtr(this, [](B*){})); } // Empty deleter. Nothing happens when shared_ptr goes out of scope. Note that c_func cannot take ownership of the pointer.
于 2011-01-22T00:38:53.177 に答える