はい、不完全な型でAshared_ptr
を宣言できます。型は、初期化またはリセットするまで完全である必要はありません。
新しいオブジェクトを指すように aを初期化またはリセットするshared_ptr
と、オブジェクトを破棄するために使用できる「deleter」が作成されます。たとえば、次のことを考慮してください。
// somewhere where A is incomplete:
std::shared_ptr<class A> p;
// define A
class A { /* ... */ };
p.reset(new A());
を呼び出すと、を使用してインスタンスを作成しているためreset
、は完了です。この関数は、 を使用してオブジェクトを破棄するために使用されるデリータを内部的に作成および保存します。はここで完了しているため、正しいことを行います。A
new
reset
delete
A
delete
これにより、が宣言されたときにそれが完全であるshared_ptr
必要がなくなります。生のポインターを受け取るコンストラクターが呼び出されたとき、または生のポインターで呼び出したときにのみ、それが完了する必要があります。 A
shared_ptr<A>
A
shared_ptr
reset
これら 2 つのことのいずれかを行うときにifA
が完全でないshared_ptr
場合は、正しいことを行わず、動作が未定義であることに注意してください (これは のドキュメントで説明されていますboost::shared_ptr
。使用shared_ptr
しているバージョンshared_ptr
(Boost、TR1、C++0x など))。
ただし、常に のベスト プラクティスに従っている限り、特に、を呼び出した結果のポインターを使用して直接shared_ptr
初期化およびリセットする場合は、この規則に違反することを心配する必要はありません。shared_ptr
new
この機能は無料ではありません shared_ptr
。deleter ファンクターへのポインターを作成して保存する必要があります。通常、これは、強い参照カウントと弱い参照カウントを格納するブロックの一部としてデリータを格納するか、そのブロックの一部としてデリータを指すポインタを持つことによって行われます (独自のデリータを提供できるため)。
auto_ptr
(そしてunique_ptr
また) オーバーヘッドがないように設計されています: その操作は、ダム ポインターを使用するのと同じくらい効率的であると想定されています。したがって、auto_ptr
この機能はありません。