最近、_unique_ptr
_も_shared_ptr
_も適切な解決策ではないように見えるという問題が発生しました。したがって、別の種類のスマートptr(以下で説明)を発明することを検討していますが、「確かに私はこれを最初に望んでいるのではありません」と考えました。
だから私のハイレベルな質問は:
std::
_機能)でこれを実現する方法はありますか?おそらく何か不足していますか?要件:
unique_ptr
_ のように単一の所有権が欲しいshared_ptr
_の動作とは異なり)単一の所有ポインタが停止した場合にのみ、基になるオブジェクトを解放する必要があります。weak_ptr
_のようなものですが、単一の所有権モデルで使用されます。動機付けの例:
インターフェイスポインターのリストを反復処理し、それらのメソッドを呼び出しているとします。これらのメソッドの一部は、リストの後半の項目が削除される原因となる場合があります。
単純なポインタを使用すると、削除されたアイテムの参照がぶら下がっています。
提案された設計:
所有ポインタ_my_ptr
_および非所有参照_my_weak_ptr
_を呼び出します。
特定のオブジェクトについて、次のような図が表示される場合があります。
_ _______
my_ptr<Obj> owner ---------> |Obj* | -------> [Obj data ... ]
+----> |count|
| +--> |_____|
my_weak_ptr<Obj> A ---+ |
|
my_weak_ptr<Obj> B -----+
_
_my_ptr
_には、_unique_ptr
_とほぼ同じインターフェースがあります。内部的には、実際には単なる「実際の」ポインタである「制御ブロック」へのポインタと、制御ブロック自体の参照カウントを格納します。破棄時に、_my_ptr
_は制御ブロックポインタをNULLに設定し、refcountをデクリメントします(必要に応じて制御ブロックを削除します)。
_my_weak_ptr
_はコピー可能であり、実際の_Obj*
_を返すget()
メソッドがいくつかあります。ユーザーはこれを使用する前にNULLをチェックする必要があります。破棄時には、_my_weak_ptr
_はカウントを減らします(必要に応じて、制御ブロックを削除します)。
欠点は、アクセスごとにメモリを2回ホップすることです。 _my_ptr
_の場合、これは真の_Obj*
_を内部に格納することでも軽減できますが、_my_weak_ptr
_参照は常にそのダブルホップコストを支払う必要があります。
編集:リンクからのいくつかの関連質問:
したがって、このようなものに対する需要があるようですが、スラムダンクソリューションはありません。スレッドセーフが必要な場合は、_shared_ptr
_および_weak_ptr
_が適切な選択ですが、そうでない場合は、不要なオーバーヘッドが追加されます。
_boost::local_scoped_ptr
_ もありますが、それでも共有所有権モデルです。 _unique_ptr
_のように、所有するポインタのコピーを防止したい。
余分なブロックを割り当てないデザインがありますが、代わりに3つのポインターのサイズのポインターオブジェクトを作成します。ポインターは二重リンクリストのノードであり、各弱参照は同じリストのノードです。
欠点は、直線的な削除の複雑さ(各参照を無効にする必要がある)であり、これを効率的にスレッドセーフにすることは不可能です。
利点は、共有ポインターと弱いポインターの両方の高速逆参照です。
どこでこのアイデアを見たり聞いたりしたのか正確には覚えていません...