最新のC++(03-gccなどの最近のコンパイラを使用していると仮定)では、typeidキーワードを使用して、少なくとも実行時に基本的な型情報を提供するtype_infoオブジェクトを取得できます。これは標準(およびクロスプラットフォーム)機能です。。
ウィキペディアから例を取り、テンプレート/継承チェックを追加しました。これはうまく機能しているようですが、intバージョンについてはわかりません(これは、コンパイラが読み取り専用のどこかに型名を持っているという仮定を悪用するハックですメモリスペース...それは間違った仮定かもしれません)。
文字列識別子は、あなたの場合にそれを使用できるのであれば、クロスプラットフォームの識別にははるかに優れているようです。コメントで示唆されているように、名前は標準で「実装定義」されているため、クロスコンパイラとの互換性はありません。
完全なテストアプリケーションコード:
#include <iostream>
#include <typeinfo> //for 'typeid' to work
class Person
{
public:
// ... Person members ...
virtual ~Person() {}
};
class Employee : public Person
{
// ... Employee members ...
};
template< typename DERIVED >
class Test
{
public:
static int s_id()
{
// return id unique for DERIVED
// NOT SURE IT WILL BE REALLY UNIQUE FOR EACH CLASS!!
static const int id = reinterpret_cast<int>(typeid( DERIVED ).name());
return id;
}
static const char* s_name()
{
// return id unique for DERIVED
// ALWAYS VALID BUT STRING, NOT INT - BUT VALID AND CROSS-PLATFORM/CROSS-VERSION COMPATBLE
// AS FAR AS YOU KEEP THE CLASS NAME
return typeid( DERIVED ).name();
}
};
int wmain ()
{
Person person;
Employee employee;
Person *ptr = &employee;
std::cout << typeid(person).name() << std::endl; // Person (statically known at compile-time)
std::cout << typeid(employee).name() << std::endl; // Employee (statically known at compile-time)
std::cout << typeid(ptr).name() << std::endl; // Person * (statically known at compile-time)
std::cout << typeid(*ptr).name() << std::endl; // Employee (looked up dynamically at run-time
// because it is the dereference of a pointer to a polymorphic class)
Test<int> test;
std::cout << typeid(test).name() << std::endl;
std::cout << test.s_id() << std::endl;
std::cout << test.s_id() << std::endl;
std::cout << test.s_id() << std::endl;
std::cout << test.s_name() << std::endl;
Test< Person > test_person;
std::cout << test_person.s_name() << std::endl;
std::cout << test_person.s_id() << std::endl;
Test< Employee > test_employee;
std::cout << test_employee.s_name() << std::endl;
std::cout << test_employee.s_id() << std::endl;
Test< float > test_float;
std::cout << test_float.s_name() << std::endl;
std::cout << test_float.s_id() << std::endl;
std::cin.ignore();
return 0;
}
出力:
class Person
class Employee
class Person *
class Employee
class Test<int>
3462688
3462688
3462688
int
class Person
3421584
class Employee
3462504
float
3462872
これは少なくともVC10Beta1とVC9で機能し、GCCで機能するはずです。ちなみに、typeid(およびdynamic_cast)を使用するには、コンパイラで実行時型情報を許可する必要があります。デフォルトでオンになっているはずです。一部のプレートフォーム/コンパイラ(一部の組み込みハードウェアについて考えています)では、RTTIはコストがかかるためオンになりません。したがって、極端な場合には、より良い解決策を見つける必要があります。