C++
RTTI: informazioni di tipo run-time
Ricerca…
Nome di un tipo
È possibile recuperare il nome definito di implementazione di un tipo in runtime utilizzando la funzione membro .name()
dell'oggetto std::type_info
restituito da typeid
.
#include <iostream>
#include <typeinfo>
int main()
{
int speed = 110;
std::cout << typeid(speed).name() << '\n';
}
Output (definito dall'implementazione):
int
dynamic_cast
Usa dynamic_cast<>()
come una funzione, che ti aiuta a buttare giù attraverso una gerarchia di ereditarietà ( descrizione principale ).
Se devi eseguire un lavoro non polimorfico su alcune classi derivate B
e C
, ma hai ricevuto la class A
base class A
, scrivi in questo modo:
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();
}
La parola chiave typeid
La parola chiave typeid
è un operatore unario che fornisce informazioni sul tipo di esecuzione sul suo operando se il tipo dell'operando è un tipo di classe polimorfico. Restituisce un lvalue di tipo const std::type_info
. La qualifica di cv di alto livello viene ignorata.
struct Base {
virtual ~Base() = default;
};
struct Derived : Base {};
Base* b = new Derived;
assert(typeid(*b) == typeid(Derived{})); // OK
typeid
può anche essere applicato direttamente a un tipo. In questo caso, i primi riferimenti di livello superiore vengono rimossi, quindi la qualifica di cv di livello superiore viene ignorata. Pertanto, l'esempio precedente potrebbe essere stato scritto con typeid(Derived)
invece di typeid(Derived{})
:
assert(typeid(*b) == typeid(Derived{})); // OK
Se typeid
viene applicato a qualsiasi espressione che non sia di tipo di classe polimorfico, l'operando non viene valutato e il tipo di informazioni restituito è per il tipo statico.
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 unevaluated
Quando usare quale cast in c ++
Utilizza dynamic_cast per convertire i puntatori / riferimenti all'interno di una gerarchia di ereditarietà.
Usa static_cast per le conversioni di tipo ordinario.
Usa reinterpret_cast per la reinterpretazione a basso livello dei pattern di bit. Usare con estrema cautela.
Usa const_cast per lanciare via const / volatile. Evita questo se non sei bloccato usando un'API const-errata.