2013-04-21 14 views
7

Supponiamo di avere una classe di base astratta Parent e sottoclassi Child1 e Child2. Se ho una funzione che richiede un genitore *, c'è un modo (forse con RTTI?) Per determinare in fase di esecuzione se si tratta di un Child1 * o Child2 * che la funzione effettivamente ricevuto?Identificazione di una sottoclasse con un puntatore alla sua classe base?

La mia esperienza con RTTI qui, finora, è stata che quando foo è un genitore *, typeid (foo) restituisce typeid (Parent *) indipendentemente dalla classe figlio di cui foo è membro.

+2

Un 'Parent *' è sempre un 'Parent *'. È * mai * un 'Bambino *'. Quello che intendi chiedere è "qual è il tipo di cosa a cui punta". –

+0

Kerrek SB: Ieri ti ho dato la fredda spalla, ma quando sono arrivato alla programmazione vera e propria, il tuo commento era probabilmente più prezioso di qualsiasi altra cosa sulla pagina. Mi dispiace ... – ExOttoyuhr

risposta

5

devi guardare il typeid del puntatore Dereferenced, non il puntatore stesso; I., typeid (* foo), non typeid (foo). Chiedendo il puntatore dereferenziato otterrà il tipo dinamico; chiedere informazioni sul puntatore stesso ti darà il tipo statico, come osservi.

+0

Sembra una misura più esatta di ciò che stavo cercando rispetto alla creazione di numerosi puntatori di sottoclasse, sarebbe stato ... – ExOttoyuhr

+0

Vale la pena ricordare che 'typeid (* foo)' restituirà solo il tipo di runtime corretto (cioè ' Child1' invece di 'Parent') se la classe genitore ha almeno un metodo virtuale. – ApproachingDarknessFish

2

Certo:

BaseClass *bptr = // whatever, pointer to base class 
SubclassOne *safe_ptr_one = dynamic_cast<SubclassOne *>(bptr); 
if (safe_ptr_one != nullptr) { 
    // Instance of SubclassOne 
} else { 
    // not an instance of SubclassOne, try the other one 
    SubclassTwo *safe_ptr_two = dynamic_cast<SubclassTwo *>(bptr); 
    if (safe_ptr_two != nullptr) { 
     // Instance of SubclassTwo 
    } else { 
     // it wasn't either one :'(
    } 
} 
+0

Nice - Non sapevo che dynamic_cast potesse farlo! (Ma poi, è per questo che ho chiesto.) – ExOttoyuhr

+0

@ExOttoyuhr Prego. E yay, sono riuscito a fornire una risposta prima di Andy Prowl! –

5

È possibile utilizzare std::dynamic_cast per questo.

Parent* ptr = new Child1(); 
if(dynamic_cast<Child1*>(ptr) != nullptr) { 
    // ptr is object of Child1 class 
} else if(dynamic_cast<Child2*>(ptr) != nullptr) { 
    // ptr is object of Child2 class 
} 

Anche se si utilizza puntatori intelligenti, come std::shared_ptr, è possibile controllare in questo modo:

std::shared_ptr<Parent> ptr(new Child1()); 
if(std::dynamic_pointer_cast<Child1>(ptr) != nullptr) { 
    // ptr is object of Child1 class 
} else if(std::dynamic_pointer_cast<Child2>(ptr) != nullptr) { 
    // ptr is object of Child2 class 
} 
Problemi correlati