趣味は車輪の再発明♪

[C++] typeidで実行時型情報(RTTI)を取得する


詳解 OpenCV ―コンピュータビジョンライブラリを使った画像処理・認識
Gary Bradski Adrian Kaehler
オライリージャパン
売り上げランキング: 25,746


■ たかみんつ / ソフト開発メモINDEX / C++インデックス /


実行時型情報

C++標準の実行時型情報(RTTI - Runtime Type Information)は、 typeid演算子で得られるtype_infoクラスのインスタンスです。

typeidは演算子ですので、関数ではないのだけれど、あえて関数プロトタイプ的に表せば、以下のようになっています。

#include <typeinfo> //type_infoが宣言されています
const type_info& typeid( 式 ) //①
const type_info& typeid( 型 ) //②

type_infoインスタンスへの定数参照が得られるんですね。 「式」には、変数やポインタなどを与えられます。定数式でもOKでした。1.1を与えるとdoubleになっていましたが、1.0ではナゼかintの型情報を返してきていました。 「型」はプリミティブ型や、クラス、構造体などの名前ですね。ただし、参照型に関しては、参照先の型情報になるようです(後述)。

実行時に型名を得る

type_infoから型の名称を得るには、name()メソッドを使用します。

#include <iostream>
#include <typeinfo>
using namespace std;
void main() {
    int a = 0;
    cerr << typeid(a).name() << endl;
}

上のプログラムを実行すると "int" と表示されます。

#include <iostream>
#include <typeinfo>
using namespace std;
void main() {
    int a = 0;
    cerr << typeid(int).name() << endl;// int

    int* pa = &a;
    cerr << typeid(*pa).name() << endl;// int 
    cerr << typeid(pa).name() << endl;// int *

    const int& cra = a;
    cerr << typeid(cra).name() << endl;// int

    cerr << typeid(type_info).name() << endl;// class typeinfo
}

参照型は参照型としてでなく、参照先の型名になるんですね。

コンストラクタ、デストラクタでの typeid(*this) は注意が必要

typeid演算子を使えば、基本クラスへのポインタで派生クラスの実行時型情報へアクセスできますが、 ただし、基本クラスのコンストラクタやデストラクタ内でtypeinfo(*this)とした場合は、基本クラスのクラス情報しか得られません。 (VC++で確認)

基本クラスのコンストラクタを実行している時は、まだ派生クラスでの実装部分は構築されていません(メンバイニシャライザの手前で基本クラスのコンストラクタが実行されていると考えられる)。 逆に、デストラクタも基本クラスの破棄の最中は、既に派生クラスの実装が破棄されているので、同じ状況です。

つまり、

基本クラスのコンストラクタやデストラクタの内部でのthisポインタは、派生クラスのインスタンスを参照していない

ということですね。だから、typeid(*this).name()とやっても派生クラスのクラス名は得られない。

基本クラスのコンストラクタ内で、仮想関数を呼び出しても、派生クラスの実装が呼ばれることがないのと同じ理由ですね。


Pythonプロフェッショナルプログラミング 第2版
秀和システム (2015-05-21)
売り上げランキング: 1,813


クラウドではじめる機械学習 Azure MLでらくらく体験
脇森浩志 杉山雅和 羽生貴史
リックテレコム
売り上げランキング: 2,081

実践Node.js プログラミング (Programmer's SELECTION)
Mike Cantelon Marc Harter T.J. Holowaychuk Nathan Rajlich
翔泳社
売り上げランキング: 40,213

■ たかみんつ / ソフト開発メモINDEX / C++インデックス /



RSS Feed Widget
[C++] typeidで実行時型情報(RTTI)を取得する
(http://bicycle.life.coocan.jp/takamints/index.php/doc/cplusplus/typeid)
by Koji Takami ( email: vzg03566@gmail.com, GitHub: takamin )