リファレンスカウントを実装するC++クラスがあり、このクラスのすべてのユーザーが、このクラスから仮想的にのみ継承して、複数の参照カウンタでオブジェクトが終了しないようにします。特定のクラスの仮想継承を検出してアサートする方法はありますか?
私は、コンパイル時または少なくとも実行時にいずれかのこの需要量を主張するいくつかの方法をしたいと思います。
これを達成する方法はありますか?
リファレンスカウントを実装するC++クラスがあり、このクラスのすべてのユーザーが、このクラスから仮想的にのみ継承して、複数の参照カウンタでオブジェクトが終了しないようにします。特定のクラスの仮想継承を検出してアサートする方法はありますか?
私は、コンパイル時または少なくとも実行時にいずれかのこの需要量を主張するいくつかの方法をしたいと思います。
これを達成する方法はありますか?
私は、クラスをラップする最も簡単な選択肢になると思います。 RefCounterから直接継承するのではなく、中間クラスを作成します。
struct RefCounterVirtPrivate_
{
int count;
RefCounterVirt()
: count(0)
{ }
};
struct RefCounter : public virtual RefCounterVirtPrivate_
{
};
struct A : public RefCounter { };
struct B : public RefCounter { };
struct C : public A, public B { };
その後、すべてが仮想継承を気にする必要なしRefCounter
から継承することができます。既存のコードを変更する必要はありません。RefCounter
の仮想継承自体は無害です。当然の
これは、人々が直接RefCounterVirtPrivate_
から継承しません保証するものではありませんが、私はそれを明らかに名前を与えてくれた理由です。誤ってこれを行うことは、virtual
というキーワードを忘れるよりも難しくなります。
これは、いくつかの策略で可能であってもよいが、影響を考慮する必要があります。あなたはその参照カウンタがこれまでにゼロに達した場合、オブジェクトがすぐに自己破壊する必要がポリシーを設定しています。それはオブジェクトの実装にdelete this;
を呼び出したときに
アプリケーションに応じて、すなわち唯一の具体的な実装がに表示させた(基底クラスでadd_ref()
とrelease()
抽象的機能を持って、正確な時間を残しておきたいかもしれませんすべてのインタフェースvtableが適切なサンクを持つ)、具体的なクラスに参照カウントを維持する負担をかける。
これは何ですか?
struct RefCounter {
template <typename T>
RefCounter(T *) {
BOOST_STATIC_ASSERT(boost::is_virtual_base_of<RefCounter, T>);
}
};
struct GoodClass : virtual RefCounter {
GoodClass() : RefCounter(this) {}
};
struct BadClass : RefCounter {
BadClass() : RefCounter(this) {}
};
それは派生型をキャプチャするために、しかし、コンストラクタにthis
を渡す必要がおよそ残念です。もちろん、意図的に鈍ったユーザーはthis
以外のものを渡すことでそれを覆す可能性があります。
'this'の代わりにCRTPを使うこともできますが、あなたの解決策は良いと思います。 – sbi
@sbi:私はと考えているが、その後、 'RefCounter
クラスが2つの基底から継承し、1つの基底が実質的に 'RefCounter'から継承し、もう1つが実質的に継承しない場合、これは動作しますか? – sharptooth
実はこのクラスは 'すべての回でthis'自体を削除しないので、私は'のAddRef() '/'リリース() 'でチェックを行うことができます。そのトリッキーは大歓迎です。 – sharptooth