2012-08-28 27 views
14

I tienen clase base A, clase B hereda de A, clase C, que es una clase de plantilla hereda de A. clase D hereda de C. La relación es la siguiente:sobre reparto dinámico el C++ con clase de plantilla

 A 
    /\ 
     B C (template class) 
      \ 
      D 

Puedo crear un objeto A O1 con el objeto D D1, luego deseo hacer una conversión dinámica O1 a un objeto C1 de tipo C. Pero creo que falla. Mi pregunta es por qué este proceso falla?

Luego uso static_cast para crear el objeto de tipo C C2 del objeto D D1, y comprobé que C2 tiene el valor correcto de D2. ¿Siempre es exitoso convertir del tipo D al tipo C usando static_cast?

Gracias!

+1

Publique el código completo, junto con los resultados esperados y reales. Hay un número infinito de cosas que podrían estar yendo mal, y no podemos decir cuál es sin un código específico. – Mankarse

+0

¿Su clase base tiene funciones virtuales? Si no, no puedes usar 'dynamic_cast'. – GManNickG

+0

Tenga en cuenta que la mayoría de estas conversiones solo son válidas para los punteros y las referencias, no para los objetos mismos. No está claro a partir de su descripción exactamente lo que está tratando de convertir; algún código de ejemplo sería útil. –

Respuesta

13

Bueno, ya que C es una plantilla, no es un tipo y no se puede utilizar como un objetivo de un elenco (ni dinámico a estático), y no se puede derivar de ella. Necesita instanciar la plantilla de clase. La clase resultante puede usarse en un molde. Esto es, el siguiente trabajo:

struct A { }; 
template <typename T> struct C : A { }; 
struct D : C<int> { }; 

D d; 
A& a = d; 
C<int>& c = static_cast<C<int>&>(a); // or dynamic_cast, if `A` were polymorphic 
+1

dynamic_cast sería un comportamiento indefinido aquí, ya que desciende con un tipo no polimórfico (debe agregar al menos una función virtual para hacer que dynamic_cast funcione). – IceCool

+1

@IceCool Correcto, agregué una aclaración. –

+0

Si tiene 'error C2683: 'dynamic_cast': '...' no es un tipo polimórfico' simplemente agregue un * virtual destructor * a la clase base:' virtual ~ A() {} ' – 56ka

9

a un tipo C objeto C1. Pero encuentro que falla.

Dado que C es una plantilla, realmente no existe el "tipo C". Más bien hay C<int> o C<Foo>. (suponiendo que tiene una plantilla arg). Las plantillas solo se convierten en clases cuando están especializadas.

Así que si D heredados de un tipo específico de C:

class D : public C<int> 
{ 
}; 

que podría dynamic_cast hasta un C<int>, pero no quiere decir un C<float>

Para ayudar a explicar mejor, su árbol de herencia es realmente

  A 
    /| \ 
C<float>... C<int> 
      | 
      D 

So C no es un padre de D, pero C<int> es en este ejemplo. Las instancias de C en sí mismas no existen en realidad en el tiempo de ejecución, sus únicas instancias completamente especificadas de C<type> que realmente existen.

+1

No solo en tiempo de ejecución -' C' no es un tipo, punto. –

Cuestiones relacionadas