shared_ptr
が必要な場合は、unique_ptr
で始まります。それから、ビルドアップ。
struct cleanup_obj {
// not called with nullptr:
void operator()(obj* t)const {
obj_unref(t);
}
};
using obj_unique_ptr = std::unique_ptr<T, cleanup_obj>;
using obj_shared_ptr = std::shared_ptr<T>;
template<class T>
obj_unique_ptr<T> make_unique_refcount(T* t) {
using ptr=obj_unique_ptr<T>;
if (!t) return ptr();
obj_ref(t);
return ptr(t);
}
template<class T>
obj_shared_ptr<T> make_shared_refcount(T* t) {
return make_unique_refcount(t); // implicit convert does right thing
}
私は何をしましたか?
最初に私は完成したかもしれないので、unique_ptr
ラッパーを書いて、unique_ptr-> shared_ptr暗黙の変換によってshared_ptr
ケースを解決します。
unique_ptr
については、デフォルトのオブジェクト・デストロイヤーを使用していないと言います。この場合、obj_unref
とobj*
を知っているステートレス関数オブジェクトを使用しています。ステートレス関数オブジェクトは、オーバーヘッドをゼロに保ちます。
nullの場合、最初は参照を追加しません。これは無礼です。
shared_ptr
については、私たちが働いているという事実はunique_ptr
です。それは自由な機能になります。 shared_ptr
は、unique_ptr
が持っている破壊機能を喜んで保存します。 shared_ptr
タイプはデフォルトでオブジェクト破壊を消去するので、特別なオブジェクト・デストロイヤーを持っていることを伝える必要はありません。 (これは、が裸のポインタよりもゼロオーバーヘッドであり、shared_ptr<T>
は参照カウントブロックの不可避のオーバーヘッドを持っているからです。
私たちのobj_unique_ptr<T>
も、裸のポインタに対してゼロオーバーヘッドであることに注意してください。かなり頻繁に、共有されたものの代わりにこれらのうちの1つが必要になります。あなたがしたい場合
さて、あなたは、shared_ptr
よりも少ないオーバーヘッドで、押し付けがましいポインタでフルにobj_unique_ptr
をアップグレードすることができます。
template<class T>
struct obj_refcount_ptr : obj_unique_ptr<T> // public
{
// from unique ptr:
obj_refcount_ptr(obj_unique_ptr<T> p):obj_unique_ptr<T>(std::move(p)){}
obj_refcount_ptr& operator=(obj_unique_ptr<T> p){
static_cast<obj_unique_ptr<T>&>(*this)=std::move(p);
return *this;
}
obj_refcount_ptr(obj_refcount_ptr&&)=default;
obj_refcount_ptr& operator=(obj_refcount_ptr&&)=default;
obj_refcount_ptr()=default;
obj_refcount_ptr(obj_refcount_ptr const& o):
obj_refcount_ptr(make_unique_refcount(o.get())
{}
obj_refcount_ptr& operator=(obj_refcount_ptr const& o) {
*this = make_unique_refcount(o.get());
return *this;
}
};
私はそれをカバーすると思います。これは、割り込み型のスマートポインタをカウントするゼロオーバヘッドのリファレンスです。これらの侵入型スマートポインタは、unique_ptr
であるため、暗黙の変換によってstd::shared_ptr<T>
に変換することができます。彼らはちょうどunique_ptr
私たちは自分自身をコピーするために教えているsです!
obj_refcount_ptr
からshared_ptr
に移動する必要があります。
operator std::shared_ptr<T>() const {
return obj_refcount_ptr(*this);
}
*this
のobj_refcount_ptr
コピーをcreatresとshared_ptr
にそれを移動する:私たちは、この問題を解決することができます。 add refは1つだけ呼び出され、remove refはshared_ptr
が0になると呼び出されます。
一般的なアプローチは、私たちにshared_ptr
、最終的にrefcount_ptr
を取得するには、その実装を悪用し、その後、最も単純なスマートポインタ(unique_ptr
)で始まる右のそれを取得することです。 unique_ptr
の実装を孤立してテストすることができます。その正確さは、より豊富なポインタのテストを容易にします。
[どのようにしてstd :: shared \ _ptrを呼び出しませんかdelete()](http://stackoverflow.com/questions/20131877/how-do-you-make-stdshared-ptr-not- call-delete) – user4581301
これはboost :: intrusive_ptrが存在する理由ではありません。 –
@ n.m。 boost :: intrusive_ptrをsupreseedする標準ライブラリにretain_ptrを追加する[proposal](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0468r0.html)もあります。 h –