ゲームが作れるようになるまでがんばる日記

ゲーム制作のことを中心にゲームに関することを書いています

typeid演算子

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は無効になってしまう。