typeid演算子を使えばクラス名の文字列を取得することが出来る。ASSERTなどのデバッグで表示するのに便利だろう。
const char* name = typeid(変数名).name();
また派生クラスのインスタンスを親クラスのポインタに代入して使うと、ポインタを見ただけではインスタンスがどの派生クラスから生成されたのか分からなくなってしまう。こんなときにもtypeid演算子が使える。というかもともとこちらが本来の使い方だろう。
でも、いろんな派生クラスを親クラスのポインタで同じように扱えて便利なのがポリモーフィズムなんだから、あんまり使うことはないかもしれない。
このような実行時の型情報をRTTI(Run Time Type Information)という。
#include <stdio.h> #include <typeinfo> class CParent { public: virtual void func() { } }; class CChildA : public CParent { }; class CChildB : public CParent { }; void main() { CParent* p0 = new CChildA(); CParent* p1 = new CChildB(); printf("%s\n", typeid(p0).name()); printf("%s\n", typeid(*p0).name()); printf("%s\n", typeid(*p1).name()); printf("%s\n", (typeid(*p0) == typeid(CChildA)) ? "true" : "false" ); printf("%s\n", (typeid(*p0) == typeid(CChildB)) ? "true" : "false" ); }
実行結果
CParent * CChildA CChildB true false
上の例では親クラスに仮想関数がある。この仮想関数をなくしてしまうと、実行結果は次のようになる。
CParent * CParent CParent false false
仮想関数がないと静的結合となり、RTTIは無効になってしまう。