2011-12-12 17 views
32

¿Es posible tener herencia sin métodos virtuales? El compilador dice que el siguiente código no es polimórfico.¿No se puede abatir porque la clase no es polimórfica?

Ejemplo:

Class A(){ 
    int a; 
    int getA(){return a;}; 
} 


Class B(): A(){ 
    int b; 
    int getB(){return b;}; 
} 

En otra clase que estamos tratando de abatido de un objeto A a un objeto de B:

A *a; 
B *b = dynamic_cast<B*>(a) 

pero esto da el siguiente error:

cannot dynamic_cast ... (source type is polymorphic) 
+1

'a' no es un puntero. ¿Es así como está en tu código? – littleadv

+0

Lo siento, a es de hecho un puntero. – wbarksdale

+0

¿Y es el tiempo de compilación de error o el tiempo de ejecución? Si el tiempo de ejecución, en mi humilde opinión es el comportamiento esperado. – littleadv

Respuesta

56

No se resisten los errores de sintaxis, no se puede dynamic_cast un tipo no polimórfico. static_cast es el elenco que usaría en este caso, si sabe que, de hecho, es un objeto del tipo de destino.

La razón por la cual: static_cast básicamente hace que el compilador realice una comprobación en el momento de la compilación "¿Se podría enviar la entrada a la salida?" Esto se puede usar para los casos en los que está lanzando hacia arriba o hacia abajo una jerarquía de herencia de punteros (o referencias). Pero la verificación es solo en tiempo de compilación, y el compilador supone que usted sabe lo que está haciendo.

dynamic_cast solo se puede utilizar en el caso de un puntero o modelo de referencia, y además de la verificación de tiempo de compilación, se hace un tiempo de ejecución adicional para verificar que el lanzamiento sea legal. Requiere que la clase en cuestión tenga al menos 1 método virtual, que permite al compilador (si es compatible con RTTI) realizar esta comprobación adicional. Sin embargo, si el tipo en cuestión no tiene ningún método virtual, entonces no se puede usar.

El caso más simple, y probablemente valga la pena si está aprobando punteros como este, es considerar la posibilidad de hacer virtual el destructor de la clase base. Además de permitirle usar el molde dinámico, también permite llamar a los destructores apropiados cuando se elimina un puntero de clase base.

+0

Muchas gracias por el conocimiento. Eso funcionó. – wbarksdale

2
A a; 
B *b = dynamic_cast<B*>(a) 

Aquí a es un objeto yb es un puntero.

En realidad, la subida y la bajada están permitidas en C++. Pero al usar downcasting, se deben prestar atención a 2 cosas: 1 La superclase debe tener al menos un método virtual. 2 Dado que la superclase es "más pequeña" que la subclase, se debe usar el objeto de memoria con cuidado.

4

sí, dynamic_cast para tipos no polimórficos no están permitidos. La clase base debe tener al menos un método virtual. Solo entonces esa clase puede llamarse polimórfica.

En este artículo se explica un ejemplo similar: http://www.cplusplus.com/doc/tutorial/typecasting/

+0

Dave dio una buena respuesta. No tengo privilegios para comentar sobre su publicación. Entonces, estoy comentando aquí. –

18

Se necesita al menos un método virtual en una clase para run-time type information (RTTI) para aplicar con éxito el operador dynamic_cast.

11

acaba de hacer A destructor virtual (siempre lo hago para cualquier clase solo por seguridad).

+7

no para ninguna clase sino para la clase que pretende ser una clase base – ParokshaX

Cuestiones relacionadas