アルフが言うように、これは必要ありません。 typeid
はすでに識別子が整数ではありませんが、一意のクラス識別子を与えています。私は、「共通の基底クラス」の条件を緩和することが許可されていた場合だけで笑いのために、:
inline unsigned int counter() {
static unsigned int count = 0;
return ++count;
}
struct BaseClass {
virtual unsigned int GetID() = 0;
virtual ~BaseClass() {}
};
template <typename D>
struct IntermediateClass : BaseClass {
virtual unsigned int GetID() {
static unsigned int thisid = counter();
return thisid;
}
};
// usage
struct Derived : IntermediateClass<Derived> {
...
};
あなたはそれがマルチスレッドプログラムで使用するかどうcounter
にスレッドセーフを追加する必要があると思います。
明らかに、IDは、プログラムの特定の実行内で一意でしかありません。
継承階層が深く、異なるクラスの署名が異なるコンストラクタがたくさんある場合は、派生クラスと直接ベースクラスの間にIntermediateClassを挿入する必要があるため、少し毛深いです。次のようにしかし、あなたは常にすべてのことの救済することができます
inline unsigned int counter() {
static unsigned int count = 0;
return ++count;
}
struct BaseClass {
virtual unsigned int GetID() = 0;
virtual ~BaseClass() {}
};
template <typename D>
unsigned int ThisID(const D *) {
static unsigned int thisid = counter();
return thisid;
}
// usage
struct Derived : BaseClass {
// this single line pasted in each derived class
virtual unsigned int GetID() { return ThisID(this); }
...
};
私はここに新しい言語機能のための「機会」が存在だと思う:1とテンプレート関数として基底クラスで定義されている仮想関数を " typename "テンプレートパラメータであり、派生クラスをテンプレート引数として使用して、派生クラスごとに自動的にオーバーライドされます。架空の構文、仮想テンプレート関数が不正なので:
struct BaseClass {
template <typename Derived>
virtual unsigned int GetID() {
static unsigned int thisid = counter();
return thisid;
}
virtual ~BaseClass() {}
};
再実装自分自身をRTTIしたい、心に基づいて言語機能を正当化するのは難しい...
のIDは、intであるか、任意の一意の型である必要があります。 typeidによって返されたものあなたのBaseClassは多態性ですか? – Chubsdad
私の基本クラスは多相ですが、RTTI(性能とメモリの両方)に伴うオーバーヘッドの正確な性質について、堅実で完全な説明を見つける能力がないため、私はそれを完全に避けようとしています。 – Dan