4

この場合に auto_ptr が役立つかどうかはよくわかりません。

class A
{
  A(const B& member)
   : _member(B)
  {};

...
  const B& _member;
};


A generateA() {
   auto_ptr<B> smart(new B());
   A myA(*smart);
   return myA;
}

囲んでいるスコープを離れると、myA._member参照は有効になりますか? smartここで auto_ptr が答えではない場合、それは何ですか?

編集:私が皆を混乱させたところがわかります。スコープ外で myA を返さなければならないため、 smart がスコープを終了した後に _member が有効であることを気にします。

4

3 に答える 3

6

それはあなたを助けません。_member はダングリング ハンドルになります。これはauto_ptr、スコープの終わりでの破棄が保証されいるためです。

考えられる答えは 2 つあります。

  • _member の type を作成できますboost::shared_ptr<const B>
  • または、クラス B がsmallcopyablemonomorphicであり、 object identityを保持する必要がない場合、 _member を値にして、そこに引数のコピーを保存できます。これは断然最も簡単なオプションですが、明らかに制限があります。

あなたの編集に応えて:それは確かに私が話していたケースです. myA を値で返すことにより、コピーが作成され、コピーの _member は既に破棄されたローカルを参照します。説明したように、両方shared_ptrと値のセマンティクスがこれを解決します。

于 2009-03-09T17:45:55.890 に答える
2

このauto_ptrクラスは、通常のポインターのラッパーです。スタックが巻き戻されたときに割り当て解除を処理します ( のデストラクタauto_ptrが呼び出され、含まれているオブジェクトが解放されます)。

Aオブジェクトもスタック上に作成されることに注意してください。スコープが終了すると、A と auto_ptr の両方が解放されます。この時点を超えてAオブジェクトにアクセスしようとすると、コンパイル時エラーが発生します。

Aオブジェクトがブロックの外のどこかに作成されたと仮定すると、実際の問題が発生します。オブジェクトはオブジェクトへの参照A格納するため、ブロック スコープ外では、この参照は無効になります。B

auto_ptrC++0x では非推奨になっていることにも注意してください。unique_ptr代わりにaを使用してください。C++0x で登場する汎用スマート ポインターを調べてください。

于 2009-03-09T17:47:31.800 に答える
0
{
   auto_ptr<B> smart(new B());
   A myA(*smart);
}

'smart' に保持されているポインターとオブジェクト 'myA' の両方が、このスコープの最後で破棄されます。しかし、それはこのコードのスニピットであなたが望むものでなければなりません。

スコープが終了すると、'myA' が最初に破棄されます (最後に宣言されます)。
次に、このスマートに続いて破棄され、そのデストラクタがポインターを削除します。

「smart」または「myA」を参照する方法がないため、この時点でポインターを削除してください。

または、これを行うこともできます:

{
    B  myB;
    A  myA(myB);
}
于 2009-03-09T18:40:38.473 に答える