または、それを行う必要がある場合は、shared_ptr を使用する必要がありますか?
3 に答える
scoped_ptr
呼び出し先がラップされたポインターを格納する必要がなく、それを使用していくつかのメソッドを呼び出すだけの場合は、参照渡ししても安全です。によって保護されたオブジェクトはscoped_ptr
、スコープ外になると破棄されます。ポインターがスタック変数の場合は呼び出し関数の終了時、メンバー変数の場合は含まれているクラス インスタンスの割り当てが解除されたときのいずれかです。
一般に、スマート ポインターはオブジェクトの所有権を管理するために存在するため、簡単に説明します。
boost::scoped_ptr
保護されたオブジェクトの有効期間を外側のスコープに制限します。所有者は 1 人だけです。- また、
std::auto_ptr
所有者は一度に 1 人だけですが、代入を介して (関数パラメーターまたは戻り値として) 所有権を渡すことができます。 boost::shared_ptr
参照カウントによる共有所有権をサポートします。保護されたオブジェクトは、参照カウントがゼロになったときにのみ破棄されます。これは最も汎用性の高いスマート ポインターですが、わずかなオーバーヘッドが発生するため、最もコストがかかります (参照カウントはアトミック操作で維持されるため、かなりコストがかかります)。循環依存の可能性もあります。boost::weak_ptr
保護されたオブジェクトがまだ生きていることを確認して実行時 にアップグレードできる非所有スマート ポインターです。boost::shared_ptr
boost::shared_array
C++ には単一オブジェクトと複数オブジェクトの個別の割り当て解除関数があるため ( operator delete
vs. operator delete[]
.) 、配列バリアントもあります。
スマート ポインターは、Resource Acquisition Is Initialization (RAII) のイディオムをサポートします。これは、例外の安全性の保証を提供する方法です。
はい、参照渡しできます。
ただし、関数が管理対象オブジェクトを使用したいだけの場合は、オブジェクト自体への参照を渡すことを検討してください。
void foo(const boost::scoped_ptr<Object>& o)
{
o->foobar();
}
void bar(const Object& o)
{
o.foobar();
}
違いは、最初のケースでは、関数を特定のスマート ポインター型と結合したことです。
Object o;
boost::scoped_ptr<Object> scoped(new Object);
boost::shared_ptr<Object> shared(new Object);
foo(o); //no
foo(scoped); //OK
foo(shared); //no
bar(o); //OK
bar(*scoped); //OK
bar(*shared); //OK
scoped_ptr
通常、意図がインスタンス自体で何かを行うことである場合にのみ、 を渡しscoped_ptr
ます (たとえば、リソースの解放またはリセット)。同様にshared_ptr
(たとえば、関数がリソースを他の共有ポインタと共有したい場合)。
個人的には、ほぼどこでも const 参照で shared_ptr を渡します。他の人が言ったように、関数を呼び出して const 参照を渡す場合、呼び出し元はほぼ確実に shared_ptr をスコープ内に保持します。
本当の利点は、この方法で参照カウンターを更新するコストを節約できることです。ウィキhttp://en.wikipedia.org/wiki/Reference_countingをざっと読むと、参照カウンターで +1 / -1 (おそらくアトミック) 操作を絶えず実行すると、キャッシュが破壊される可能性があることがわかります。