RTTI: Run-Time Type Information
Name of a type
You can retrieve the implementation defined name of a type in runtime by using the .name() member function of the std::type_info object returned by typeid.
#include <iostream>
#include <typeinfo>
int main()
{
int speed = 110;
std::cout << typeid(speed).name() << '\n';
}Output (implementation-defined):
intdynamic_cast
Use dynamic_cast<>() as a function, which helps you to cast down through an inheritance hierarchy (main description).
If you must do some non-polymorphic work on some derived classes B and C, but received the base class A, then write like this:
class A { public: virtual ~A(){} };
class B: public A
{ public: void work4B(){} };
class C: public A
{ public: void work4C(){} };
void non_polymorphic_work(A* ap)
{
if (B* bp =dynamic_cast<B*>(ap))
bp->work4B();
if (C* cp =dynamic_cast<C*>(ap))
cp->work4C();
}The typeid keyword
The typeid keyword is a unary operator that yields run-time type information about its operand if the operand’s type is a polymorphic class type. It returns an lvalue of type const std::type_info. Top-level cv-qualification are ignored.
struct Base {
virtual ~Base() = default;
};
struct Derived : Base {};
Base* b = new Derived;
assert(typeid(*b) == typeid(Derived{})); // OKtypeid can also be applied to a type directly. In this case, first top-level references are stripped, then top-level cv-qualification is ignored. Thus, the above example could have been written with typeid(Derived) instead of typeid(Derived{}):
assert(typeid(*b) == typeid(Derived{})); // OKIf typeid is applied to any expression that is not of polymorphic class type, the operand is not evaluated, and the type info returned is for the static type.
struct Base {
// note: no virtual destructor
};
struct Derived : Base {};
Derived d;
Base& b = d;
assert(typeid(b) == typeid(Base)); // not Derived
assert(typeid(std::declval<Base>()) == typeid(Base)); // OK because unevaluatedWhen to use which cast in c++
Use dynamic_cast for converting pointers/references within an inheritance hierarchy.
Use static_cast for ordinary type conversions.
Use reinterpret_cast for low-level reinterpreting of bit patterns. Use with extreme caution.
Use const_cast for casting away const/volatile. Avoid this unless you are stuck using a const-incorrect API.