Например, Я определяю класс C ++ следующим образом:
class cat : public animal
{
public:
cat(const char* nameString) : m_name(nameString) {}
~cat(){}
const char* getName() {return m_name.c_str();}
private:
std::string m_name;
};
Потом:
cat kitty("Garfield");
printf("%s", kitty.getName());
Для приведенного выше примера кода Ctags могли бы сказать мне наследование, члены, методы, тип доступа (открытый, закрытый) и т. д.
Но как я могу узнать, что котенок является примером кошки?
std::cout << "kitty is a: " << typeid(kitty).name() << '\n';
но, как вы можете увидеть, может быть не совсем то, что вы хотите.
Возвращает реализацию, определенную символьной строкой с нулевым символом в конце
содержащий название типа. Нет гарантий, в
В частности, возвращаемая строка может быть идентичной для нескольких типов и
переключаться между вызовами одной и той же программы.
Вы можете сравнить typeid
с другими известными типами, такими как cat
,
И вы можете сделать это в том же направлении / стиле, как у вас с именами объектов, и включить виртуальную функцию в Animal
:
virtual string whatAnimal()const{return "animal";}
и в производных классах:
string whatAnimal()const override {return "cat";}
Теперь у вас есть полный контроль над строкой для каждого типа, не связанной с соглашением об именах, которое вы используете в своем коде.
Можно получить имя класса объекта с помощью typeid. Тем не менее, компилятор изменяет имя, поэтому вы должны соответствующим образом разобрать его во время выполнения.
Пример:
#include <iostream>
#include <cxxabi.h>
class cls {};
void main(){
cls obj;
int status;
char * demangled_name = abi::__cxa_demangle(typeid(obj).name(),0,0,&status);
std::cout << demangled_name << std::endl;
free(demangled_name);
return;
}
будет выводить:
cls
Непосредственно ответить на ваш вопрос о том, как проверить, является ли котенок экземпляром кошки, можно следующим образом:
if(typeid(cat) == typeid(kitty))
// do something if kitty is a cat
Заметка, typeid(YourClass).name()
возвращается nYourClass
где n — длина имени класса.