2012-03-14 8 views
16

Eventuali duplicati:
C++ equivalent of instanceofC++ dynamic_cast vs typeid per il confronto di classe

Mi chiedevo che cosa la differenza tra dynamic_cast e typeid è per quanto riguarda il confronto solo di classe (a parte lo dynamic_cast che consente l'accesso ai metodi della sottoclasse e al tipo id utile solo per il confronto delle classi). Ho trovato StackOverflow di due anni facendo la stessa domanda: C++ equivalent of instanceof. Tuttavia, ha due anni e non volevo annullare un vecchio post (e non sono sicuro che sia uscito typeid), quindi ho pensato di ri-chiedere la stessa domanda con una leggera differenza.

Fondamentalmente, ho classe A e classe B, che sono entrambe sottoclassi di classe astratta C. La classe C viene presa come parametro di un metodo e voglio determinare se la classe C è realmente classe A o classe B Sia typeid e dynamic_cast funzionano correttamente, quindi questa è più una questione di best practice/prestazioni. Sto indovinando:

A* test = dynamic_cast<A*> someClassCVar 
if (test != 0) { //it is of class A } 

O

if (typeid(someClassCVar) == typeid(A)) { 
    //it is of class A 
} 

EDIT: Siamo spiacenti, ho dimenticato di includere questo po 'di informazioni. La documentazione di ActiveMQ CMS afferma di utilizzare dynamic_cast, ma penso che sia solo perché presuppone che l'utente vorrà accedere ai metodi specifici della sottoclasse. A me, sembra che typeid sarebbe la migliore prestazione se è necessario solo un confronto di classe: http://activemq.apache.org/cms/cms-api-overview.html

+1

Direi che la 'dynamic_cast' è da preferire, ma non ho origini per il mio opinione. – Constantinius

+3

'dynamic_cast someClassCVar' restituirà un valore non nullo se' someClassCVar' è un puntatore a 'A' o uno dei discendenti di' A'. 'typeid (someClassCVar) == typeid (A)' è vero solo se 'someClassCVar' è un tipo. Quindi 2 pezzi del tuo codice non sono equivalenti. – a1ex07

+3

Di solito è un odore di progettazione se un programma C++ ha bisogno di sapere a quale classe figlio punta un puntatore genitore. Dovresti almeno fare un passo indietro di 15 minuti e osservare il tuo design. –

risposta

25

V'è una differenza importante tra i due metodi:

if(A* test = dynamic_cast<A*>(&someClassCVar)) { 
    // someClassCVar is A or publicly derived from A 
} 

considerando quanto segue:

if(typeid(someClassCVar) == typeid(A)) { 
    // someClassCVar is of class A, not a derived class 
} 
+0

Ah, capisco. Quindi se non ci interessa se è A o una sottoclasse di A per qualche motivo, quale sarebbe meglio? – Jon

+2

@Jon: ovviamente il primo;) – Constantinius

+1

'dynamic_cast <>' quindi, dato che ti interessa solo l'interfaccia di 'A' e non ti interessa come è implementata. –

0

dipende se il tipo di post-elaborazione di identificazione ha bisogno di un puntatore su A o meno.

cheking typeid sarà sicuramente più veloce (dal momento che il compilatore ha generato identificatori costanti) ma non fornirà alcuna istanza A da manipolare, quindi ti obbligherà a eseguire un dynamic_cast per ottenere un'istanza A.

+4

... o static_cast se C è una classe base non virtuale per A e B – user396672