In C++, the typeid
keyword is used to determine the class of an object at run time. It returns a reference to std::type_info
object, which exists until the end of the program[1]. The use of typeid
is often preferred over dynamic_cast<class_type>
in situations where just the class information is needed, because typeid
, applied on a type or non de-referenced value is a constant-time procedure, whereas dynamic_cast
must traverse the class derivation lattice of its argument at runtime. However, you should not rely on the exact content, such as that returned by std::type_info::name()
, as this is implementation specific with respect to the compiler.
Objects of class std::bad_typeid
are thrown when typeid
is called on a dereferenced null pointer. The class is derived from std::exception
, and thrown by typeid and others.
It is generally only useful to use typeid on the dereference of a pointer or reference (i.e. typeid(*ptr)
or typeid(ref)
) to an object of polymorphic class type (a class with at least one virtual function) because these are the only expressions that are associated with run-time type information. The type of any other expression is known at compile time.
#include <iostream> #include <typeinfo> //for 'typeid' class Person { public: // ... Person members ... virtual ~Person() {} }; class Employee : public Person { // ... Employee members ... }; int main() { Person person; Employee employee; Person *ptr = &employee; Person &ref = employee; // The string returned by typeid::name is implementation-defined 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) std::cout << typeid(ref).name() << std::endl; // Employee (references can also be polymorphic) }
Output (exact output varies by system):
Person Employee Person* Employee Employee