Show Lecture.Reflection as a slide show.
<typeinfo>
header file defines the typeid
function
(really, it’s an operator, like sizeof
) and its result type,
class type_info
.
type_info::name()
returns a
implementation-defined C++ string representing the type.
type_info
objects for equality,
int alpha; short beta; const type_info &ta = typeid(alpha), &tb = typeid(beta); cout << "type of alpha: " << ta.name() << '\n' << "type of beta: " << tb.name() << '\n' << "Equal? " << boolalpha << (ta==tb) << '\n';
type of alpha: i type of beta: s Equal? false
One rarely actually instantiates the type_info
class:
float gamma; cout << "type of gamma: " << typeid(gamma).name();
type of gamma: f
You can also pass a type as an argument to typeid()
:
cout << "type of double: " << typeid(double).name();
type of double: d
Every type has a corresponding encoding:
cout << typeid(char ).name() << '\n' << typeid(unsigned char ).name() << '\n' << typeid(short ).name() << '\n' << typeid(unsigned short ).name() << '\n' << typeid(int ).name() << '\n' << typeid(unsigned int ).name() << '\n' << typeid(long ).name() << '\n' << typeid(unsigned long ).name() << '\n' << typeid(long long ).name() << '\n' << typeid(unsigned long long).name() << '\n' << typeid(float ).name() << '\n' << typeid(double ).name() << '\n' << typeid(long double ).name() << '\n';
c h s t i j l m x y f d e
class Foobar {}; cout << typeid(int * ).name() << '\n' << typeid(int ****** ).name() << '\n' << typeid(int[3] ).name() << '\n' << typeid(int[3][4][5]).name() << '\n' << typeid(main ).name() << '\n' << typeid(Foobar ).name() << '\n';
Pi PPPPPPi A3_i A3_A4_A5_i FivE Z4mainE6Foobar
For RTTI (Run-Time Type Identification), a class must have at least one virtual function.
struct Base { virtual void foo(){} }; struct D1 : Base {}; struct D2 : Base {}; void foo(Base *b) { cout << ((typeid(*b) == typeid(D1)) ? "D1\n" : "D2\n"); } int main() { D1 d1; D2 d2; foo(&d1); foo(&d2); }
D1 D2
dynamic_cast
converts a base class pointer to a derived class pointer.
If it fails, you get a null pointer.
struct Base { virtual void foo(){} }; struct D1 : Base {}; struct D2 : Base {}; void foo(Base *b) { D1 *p = dynamic_cast<D1 *>(b); cout << (p ? "D1\n" : "D2\n"); } int main() { D1 d1; D2 d2; foo(&d1); foo(&d2); }
D1 D2
typeid
or dynamic_cast
indicates that your
class hierarchy is incorrect.