Sorpresa RTTI funciona.
El RTTI(RunTime Type Identification) se puede usar para muchas cosas, lo más tÃpico es invertir la herencia con un dynamic_cast:
Base *ptr_base = ...; Derived *ptr = dynamic_cast<Derived*>(ptr_base);
Aquà las clase Derived hereda de Base, y un dynamic_cast permite saber si un puntero de tipo Base es en realidad de la clase Derived o no. Si devuelve algo distinto de 0 es que la conversión ha tenido éxito.
También se suele usar mucho el Typeid, tyepid( variable ) devuelve una clase que representa el tipo de esa clase, eso permite que los tipos se puedan comparar en tiempo de ejecución, obtener una representación en string del nombre de la clase typeid(variable).name()… etc.
Lo que no tenÃa tan claro es qué pasa cuando se hace algo como esto:
Base *ptr = ... ; std::cout << typeid(*ptr).name() << std::endl;
¿Cuál es el resultado?
Para probarlo, aunque la Wikipedia ya lo sabÃa, un programita de ejemplo:
#include <typeinfo> #include <iostream> // Clase base class Base { public: virtual void action() = 0; virtual ~Base() {} }; // Una clase derivada de base... class Derived : public Base { public: virtual void action() { std::cout << "Hi from Derived" << std::endl; } virtual ~Derived() {} }; // Una clase derivada de base (indirectamente)... class Derived2 : public Derived { public: virtual void action() { std::cout << "Hi from Derived II" << std::endl; } virtual ~Derived2() {} }; void show(Base *base) { std::cout << "Esta función recibe un puntero Base..." << std::endl; std::cout << "Puntero = " << (void*) base << " typeid = " << typeid(base).name() << std::endl; std::cout << "Realmente apuntado = " << typeid(*base).name() << std::endl; std::cout << std::endl; } int main() { Derived *ptr_d = new Derived(); Derived2 *ptr_d2 = new Derived2(); show(ptr_d); show(ptr_d2); // cast mu burro... pero valido. show( reinterpret_cast<Derived*>(ptr_d2) ); delete ptr_d; delete ptr_d2; return 0; }
y aquà su resultado:
Esta función recibe un puntero Base... Puntero = 0x804a008 typeid = P4Base Realmente apuntado = 7Derived Esta función recibe un puntero Base... Puntero = 0x804a018 typeid = P4Base Realmente apuntado = 8Derived2 Esta función recibe un puntero Base... Puntero = 0x804a018 typeid = P4Base Realmente apuntado = 8Derived2
Efectivamente, devuelve la clase real … bien pensando es cómo tiene que ser 🙂
Hermoso 🙂