6

私はいくつかのプロジェクトを使用しているboost::shared_ptrか、std::shared_ptr広範囲に使用しています(一方にこの質問に対する良い答えがあるが、もう一方にはない場合は、すぐにどちらかの実装に変換できます)。Boostの実装では、Boost.Assertを使用して、実行時operator*またはoperator->実行時に空(NULL)ポインターが検出された場合に戻らないようにします。一方、libc++の実装にはチェックが欠けているようです。

もちろん、shared_ptr使用する前にaの有効性を確認する必要がありますが、大規模な混合パラダイムコードベースを使用すると、例外をスローするバリエーションを試してみたいと思うようになります。ほとんどのコードは比較的例外を認識しており、セグメンテーション違反ではなく、せいぜい高レベルで再開可能な状態に失敗するためstd::terminate()です。

の堅牢性を維持しながら、これらのアクセサを最適にカスタマイズするにはどうすればよいshared_ptrですか?カプセル化shared_ptrするのthrowing_shared_ptrが最善の選択肢のようですが、私は魔法を破るのを警戒しています。Boostソースをコピーして、ASSERTsを適切なthrowステートメントに変更するのが最善ですか?


適切な型のためにどこでも使用される実際の型名smart_ptr<T>は、マクロから展開されたtypedefです。つまりForwardDeclarePtr(Class)、次のように展開されます。

class Class;
typedef boost::smart_ptr<Class> ClassPtr;

すべてが合格、取得、または保存されるClassPtrので、基になる型をかなり自由に置き換えることができます。これにより、潜在的なスライス/非表示の問題が軽減されると思います。

4

2 に答える 2

5

共有ポインタstd::shared_ptr<T>を逆参照するときに例外をスローするカスタムクラス内にラップした場合に削除される「魔法」は実際にはありません。NULLしたがって、新しいラッパークラスが型のすべてのセマンティクスに従っている限り、そのアプローチが機能しない理由はわかりませんstd::shared_ptr<T>

ところで、少し異なるアプローチを取ることもできます。それは、他の人が最初にラップされたデータメンバーNULLへのポインターを渡さないようにするラッパークラスを作成することです。基本的には、コンストラクターでイディオムstd::shared_ptr<T>を強制するクラスになります。std::make_shared<T>これが可能かどうかはコードの動作に基づいてわかりませんが、例外をスローするのではなく、RAIIアプローチを使用して問題を回避する別の方法です。

于 2012-09-17T02:47:39.193 に答える
5

にサブクラスstd::shared_ptr化してthrowing_shared_ptr、これら2つのメソッドをオーバーライドし、それらをアサートしてstd::shared_ptr'simplを呼び出します。throwing_shared_ptrこれは、にスライスするのではなく、どこでも使用する限り、正常に機能するはずですstd::shared_ptr

于 2012-09-17T02:47:53.840 に答える