RTTI

  • RTTI のコストを理解するを読む限り、よほどクリティカルな部分でない限り普通に使ってもよさそう。
  • RTTIを有効にするには、コマンドラインで/GRオプションを使う、または、プロパティ-ページで[C/C++ > 言語 > ランタイム型情報を有効にする]を[はい(/GR)]にする。
  • dynamic_castを使うにはRTTIを有効にしておく。
  • VC++で/GRすると_CPPRTTIプリプロセッサマクロが定義される。
  • 仮想関数を含まないクラスでは、RTTIが有効にならない。
    • デストラクタを仮想にしておくと良いかもしれません。
  • テンプレートクラスでは、テンプレート引数まで一致しないと同じ型と認識されない。

typeid(expr)
typeid(type)
const std::type_infoまたは派生クラスのlvalueを返す。

#include <typeinfo>

class type_info
{
public:
    virtual ˜type_info();
    bool operator==(const type_info& rhs) const;
    bool operator!=(const type_info& rhs) const;
    bool before(const type_info& rhs) const;
    const char* name() const;
private:
    type_info(const type_info& rhs);
    type_info& operator=(const type_info& rhs);
};
ISO IEC 14882-2003 18.5.1より引用

実験

class A ...
class B : public A ...

int i = 0;

std::cout << typeid(i).name() << std::endl;
std::cout << typeid(int).name() << std::endl;

std::cout << "i == int ? ";
std::cout << (typeid(i) == typeid(int) ? "true" : "false")
          << std::endl;

A* pA = [[new]] B;
A& refA = *pA;

std::cout << "pA  = " << typeid(pA).name() << std::endl;
std::cout << "*pA = " << typeid(*pA).name() << std::endl;

std::cout << "A   = " << typeid(A).name() << std::endl;
std::cout << "B   = " << typeid(B).name() << std::endl;

std::cout << "refA = " << typeid(refA).name() << std::endl;

実行結果

int
int
i == int ? true

pA   = class A *
*pA  = class B
A    = class A
B    = class B

refA = class B

ISO IEC 14882-2003 18.5.1-7によるとname()の戻り値は実装定義のNULL終端文字列ということで、不思議な文字列が返ってくるかと思ったのですが、意外と分かり易くまともな文字列が返ってきました。
参照についても期待通りの動作をしてくれます。

完全なサンプルソースはRTTIのサンプル1にあります。



名前:
コメント:



ページビュー -

タグ:

+ タグ編集
  • タグ:
最終更新:2008年06月29日 11:57