2012-03-14 11 views
16

Duplicar posibles:
C++ equivalent of instanceofC++ dynamic_cast vs typeid para la comparación de clase

Me preguntaba cuál es la diferencia entre dynamic_cast y typeid es en lo que respecta a la comparación acaba de clase (aparte de dynamic_cast que permite el acceso a los métodos de la subclase y el tipo id solo es útil para la comparación de clases). Encontré un StackOverflow de dos años haciendo la misma pregunta: C++ equivalent of instanceof. Sin embargo, tiene dos años y no quería borrar una publicación anterior (y no estoy seguro de cuándo salió typeid), así que pensé en volver a hacer la misma pregunta con una pequeña diferencia.

Básicamente, tengo la clase A y la clase B, que son ambas subclases de la clase abstracta C. La clase C se toma como parámetro de un método y quiero determinar si la clase C es realmente clase A o clase B Ambos typeid y dynamic_cast funcionan correctamente, por lo que se trata más de una cuestión de mejores prácticas/rendimiento. Estoy adivinando:

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: Lo siento, se olvidó de incluir este bit de información. La documentación de ActiveMQ CMS indica que debe usar dynamic_cast, pero creo que es solo porque supone que el usuario querrá acceder a los métodos específicos de la subclase. Para mí, parece que typeid habría un mejor rendimiento si sólo se necesita una comparación de clase: http://activemq.apache.org/cms/cms-api-overview.html

+1

yo diría que el 'dynamic_cast' es preferible, pero no tengo fuentes para respaldar mi opinión. – Constantinius

+3

'dynamic_cast someClassCVar' devolverá no-null si' someClassCVar' es un puntero a 'A' o alguno de los descendientes de' A'. 'typeid (someClassCVar) == typeid (A)' es verdadero solo si 'someClassCVar' es de tipo A. Entonces 2 pedazos de tu código no son equivalentes. – a1ex07

+3

Normalmente, es un olor de diseño si un programa C++ necesita saber a qué clase secundaria apunta un puntero principal. Al menos debe dar un paso atrás durante 15 minutos y mirar su diseño. –

Respuesta

25

hay una diferencia importante entre los dos métodos:

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

Considerando lo siguiente:

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

Ahh, ya veo. Entonces, si no nos importa si es A o una subclase de A por alguna razón, ¿cuál sería mejor? – Jon

+2

@Jon: obviamente el primero;) – Constantinius

+1

'dynamic_cast <>' luego, ya que solo está interesado en la interfaz de 'A' y no le importa cómo se implementa. –

0

depende de si el procesamiento de identificación del tipo de mensaje necesita un puntero en A o no.

cheking typeid seguramente será más rápido (ya que son identificadores constantes generados por el compilador) pero no proporcionará ninguna instancia A para manipular, por lo que le obligará a realizar un dynamic_cast para obtener una instancia A.

+4

... o static_cast si C es una clase base no virtual para A y B – user396672