В современном 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 не включен, потому что он имеет свою стоимость, поэтому в некоторых крайних случаях вам нужно будет найти лучшее решение.