5

コードベースで最近見た次のコード例を考えてみてください。

void ClassA::ExportAnimation(auto_ptr<CAnimation> animation)
{
... does something
}

// calling method:
void classB::someMethod()
{
  auto_ptr<CAnimation> animation (new CAnimation(1,2));
  ClassA classAInstance;
  classAInstance.ExportAnimation(animation)
  ... do some more stuff
}

私はこれが好きではありません - そしてむしろそう書きたいです:

void ClassA::ExportAnimation(CAnimation* animation)
{
    ... does something
}

// calling method:
void classB::someMethod()
{
  auto_ptr<CAnimation> animation (new CAnimation(1,2));
  ClassA classAInstance;
  classAInstance.ExportAnimation(animation.get())
  ... do some more stuff
}

しかし、それは本当に問題ですか?

4

4 に答える 4

4

ExportAnimationそれはすべて、その内容と実装方法に依存します。

通話中のみオブジェクトを使用し、その後はそのままにしますか?

次に、参照に変換し、実際の参照を渡します。メンバーシップを渡す必要はなく、引数はオプションではないため、void ExportAnimation( CAnimation const & )十分です。利点は、メソッドにメモリ管理の問題がないことがインターフェイスから明らかであることです。渡されたオブジェクトを使用してそのままにしておくだけです。ExportAnimationこの場合、(提案されたコードのように)生のポインターを渡すことは、渡されたオブジェクトの削除に責任があるかどうかが明確でないという点で、参照を渡すよりもはるかに悪いです。

後で使用するためにオブジェクトを保持しますか?

これは、関数がスレッドを開始してバックグラウンドでアニメーションをエクスポートする場合に当てはまります。この場合、引数の有効期間は呼び出しの期間を超えて延長する必要があることを明確にする必要があります。shared_ptrこれは、関数内と関数外の両方で使用することで解決できます。これは、オブジェクトが共有されており、必要な意味がある限り存続することを伝えるためです。または、実際に所有権を譲渡することもできます。

後者の場合、所有権の譲渡が実行される場合、最初のコードは問題ありません。署名は所有権の譲渡で明示的です。それ以外の場合は、動作を文書化し、生のポインターに変更し、 を呼び出して転送を明示的にすることができますExportAnimation( myAnimation.release() )

別の回答へのコメントとしていくつかの懸念事項を追加しました。

メソッド呼び出し後にオブジェクトが存在しないことを本当に確認できますか?

呼び出し元auto_ptrは呼び出しで 0 にリセットされるため、すべての逆参照はエラーになり、最初に試行するテストでフラグが立てられます。

ヘッダー ファイルを調べて、パラメーターの型が通常のポインターではなく auto_ptr であることを確認する必要があります。

ヘッダーを見る必要はありません...生のポインターを渡してみてください。コンパイラーはauto_ptr<>、生のポインターから への暗黙的な変換はありませんauto_ptr

auto_ptr が範囲外になるまで、オブジェクトが存在することを期待します。

auto_ptrとは異なり、標準の にboost::scope_ptrはそのセマンティクスがありません。オブジェクトの所有権は解放されたり、 other に渡されたりする可能性があるため、 に保持されているオブジェクトが のスコープ全体にわたって有効であるauto_ptrという前提は、それ自体が悪いことです。auto_ptrauto_ptr

于 2010-08-09T12:29:21.043 に答える
4

auto_ptr は、ポインターの所有権が渡されることを明確に宣言します。プレーンポインターは自己文書化されていません。

于 2010-08-09T12:01:20.137 に答える
3

内部を保管場所としてのみ使用する場合、自動ptrのポイントは何ですか?

はい、それを関数に渡します。または、本当に必要ない場合は、完全に廃止します。おそらく、関数は所有権を他の何かに渡すためにそれを必要とします。

おそらくあなたが探している代替案ははるかに単純なようです:

void ClassA::ExportAnimation(CAnimation &animation) // no pointer

// calling method:
void classB::someMethod()
{
  CAnimation animation(1,2); // no pointer
  ClassA classAInstance;
  classAInstance.ExportAnimation(animation) // no ownership tranfer
  ... do some more stuff
  // object dies here, no earlier, no later
}
于 2010-08-09T12:04:28.260 に答える
1

スマートポインターを渡すことExportAnimationで、所有権が関数に渡されたことを明確に文書化し、強制します。呼び出し元がアニメーションを削除する必要はありません。この関数は、オブジェクトを明示的に削除する必要もありません。ポインタをスコープから外すだけです。

あなたの提案はそれを曖昧なままにします。ExportAnimationrawポインタを介して渡したオブジェクトを削除する必要がありますか?関数のドキュメントをチェックして、呼び出し元が何をすべきかを知る必要があります。また、実装をチェックして、実際にドキュメントとして実装されていることを確認する必要があります。

オブジェクトの存続期間を明示的かつ自動にするために、スマートポインター(およびその他のRAIIイディオム)を使用することを常にお勧めします。

于 2010-08-09T12:06:10.987 に答える