ライブラリの無効な使用 (オブジェクトが削除されたときにオブジェクトにアクセスしようとする) をトラップし、高パフォーマンスの API (API に weak_ptr と shared_ptr がない) の両方が必要な場合は、別の API を使用することを検討できます。デバッグおよび非デバッグ ビルド用。
簡単にするために、公開するオブジェクトのクラスが 1 つしかないと仮定しましょう。このクラスを Object と呼びます。内部オブジェクトにアクセスするために API から返すポインター型は、次のように定義されます。
#ifdef DEBUG
typedef ObjectPtrFacade ObjectPtr
#else
typedef Object * ObjectPtr;
#endif
ここでファサードはあなたが書くクラスです。おおよそ次のように機能します。
class ObjectPtrFacade {
public:
ObjectPtrFacade(Object *o) : wptr(o) { }
// copy constructor and assignment here etc. (not written)
Object * operator -> () const { return access(); }
Object & operator * () const { return *access(); }
private:
Object * access() {
assert(wptr.use_count() > 0);
return (Object *)(wptr.lock());
}
weak_ptr<Object> wptr;
}
このように、デバッグ ビルドをビルドするときはいつでも、オブジェクトにアクセスする前に use_count() が 0 より大きいこと、つまりオブジェクトがまだ存在することをアサートする特別な種類のスマート ポインターが使用されます。オブジェクトが解放されている場合は、失敗したアサートが発生します。これは、null ポインター参照よりも優れています。
もちろん、一般に、API の「愚かな」ユーザーがいる場合、weak_ptr を使用しても役に立たないのは、そのユーザーが lock() を呼び出して、weak_ptr が空の shared_ptr を返した後にヌル ポインター参照を作成できるためです。 ..