2009-06-21 25 views
53

C++では、変数またはゲッターにハードコードすることなく、文字列形式のクラスの名前を取得できるかどうかは疑問でした。私は、その情報のどれも実行時に実際に使用されていないことを認識しています。そのため、利用できませんが、この機能を作成するためのマクロはありますか?プログラムでC++クラス名を取得する

編集:私は実際に派生クラスの名前を取得しようとしており、Visual C++ 2008 Express Editionを使用しています。

+0

これはコンパイラに依存するため、どのコンパイラを使用しますか? –

+0

私はVisual C++ 2008 expressを使用しています。実際に派生クラスの名前を取得しようとしていることに注目すると便利ですね。 – Morgan

答えて

84

あなたがtypeidを使用することができます。

#include <typeinfo> 
cout << typeid(obj).name() << endl; 

しかし、このフォーマットが標準化されていないので、推奨され、別のコンパイラ(または同じコンパイラであっても異なるバージョン)間で異なることができます。

+0

興味深いことに、これについては分かりませんでした。それはかなりうまくいくようです。それは、私が応答で欲しかったよりも少しだけ私にテキストを与えるが、それはかなりうまくいくようだ。ありがとう! – Morgan

+0

このクラスの中には仮想メソッドがありませんか?私はRTTIはこのケースでは動作しませんが。あなたは仮想デストラクタを持っている限り、あなたは大丈夫でしょう。 – LeopardSkinPillBoxHat

+5

@LeopardSkinPillBoxHat:はい、動作します(5.2.8/3と4を参照)。 'typeid'はRTTI機能との類似性からおそらく多形型でしか動作しないというのはよくある誤解です。 - 実際、静的型に 'typeid'を使うことは、RTTIを必要とせず、使用しません。演算子はコンパイル時に評価され、結果はコンパイルされます(厳密に言えば実装の詳細ですが、これは唯一の実装です)。 –

35

あなたはちょうどそれが特定のクラスだかどうかを確認したい場合は、

typeid(obj) == typeid(CSubClass) 

は関係なく、常に実装の動作します。

virtual const char* classname() { return "CMyClass";} 

をサブクラスごとの実装:

そうでない場合は、便利な方法は、宣言することです。

+0

すばらしい解決策。簡単、シンプル、作品 - すべてのバージョンで:) –

+2

簡単、簡単、コンパイル。間違って、不幸にも。 'typeid()'はポインタである 'typeinfo *'を返します。 2つの 'typeinfo * 'ポインタが等しい場合、それらは同じ型を参照しますが、それらが等しくない場合、それらは同じ型を参照することがあります。そのため、適切なセマンティクスを持つ 'std :: type_index'クラスがあります。 ** 2つの型が等しい場合にのみ、** std :: type_index(typeid(obj))== std :: type_index(typeid(CSubClass)) 'がtrueになります。 – MSalters

8

typeid(obj).name()は、オブジェクトの実際の型(クラス)ではなく、宣言された変数の型を常に示します。 objが宣言されたクラスのサブクラスのインスタンスに変数objが代入された場合、typeidはそれを明らかにしません。

+7

GCC 4.7.3を使用して、typeid(* somePtr).name()を使用すると、具体的なクラスの名前がわかります。 – notlesh

+3

私は同じ問題に遭遇しましたが、@ stepheltonのコメントは私が実際のオブジェクトや参照の代わりにポインタで呼び出すことを実現させ、ポインタの型を返していました! '*'をすべて追加するだけです。 –

+0

上記のVSの両方のコメントを確認します。 'BaseClass * ptr = new SubClass;の後に' typeid(ptr).name() 'が' class BaseClass * 'を生成し、' typeid(* ptr).name() 'が' class SubClass'を与えます。 –

関連する問題