38

shared_ptrクラスのメンバーであるを初期化する良い方法がわかりません。私が選んだ方法がC::foo()良いのか、それとももっと良い解決策があるのか​​教えていただけますか?

class A
{
  public:
    A();
};

class B
{
  public:
    B(A* pa);
};

class C
{
    boost::shared_ptr<A> mA;
    boost::shared_ptr<B> mB;
    void foo();
};

void C::foo() 
{
    A* pa = new A;
    mA = boost::shared_ptr<A>(pa);
    B* pB = new B(pa);
    mB = boost::shared_ptr<B>(pb);
}
4

1 に答える 1

30

コードは非常に正しいです(機能します)が、次のように初期化リストを使用できます。

C::C() :
  mA(new A),
  mB(new B(mA.get())
{
}

これはさらに正確で安全です。

何らかの理由で、new Aまたはnew Bスローした場合、リークは発生しません。

スローされた場合new A、メモリは割り当てられず、例外によってコンストラクタも中止されます。何も構築されませんでした。

new Bスローされても、例外によってコンストラクターが中止mAされる場合:適切に破棄されます。

もちろん、のインスタンスにBはのインスタンスへのポインタが必要なのでA、メンバーの宣言順序は重要です。

あなたの例ではメンバー宣言の順序は正しいですが、逆にすると、コンパイラはおそらくmB以前に初期化されたビーについて文句を言いmA、のインスタンス化はmB失敗する可能性があります(mAまだ構築されていないため、呼び出しmA.get()は未定義の動作を呼び出します)。


また、コンストラクターのパラメーターとしてaのshared_ptr<A>代わりに使用することをお勧めします(それが理にかなっていて、少しのオーバーヘッドを受け入れることができる場合)。おそらくもっと安全でしょう。A*B

Bおそらく、のインスタンスはインスタンスなしでは生きられないことが保証されてAおり、私のアドバイスは当てはまりませんが、これに関する決定的なアドバイスを提供するためのコンテキストがここにありません。

于 2010-08-23T07:22:38.080 に答える