2010-09-28 16 views
5

Por ejemplo tengo un código como que¿Es posible dynamic_cast de una clase base a otra?

class Base1 
{ 
    virtual void wonderFULL() = 0; 
}; 

class Base2 
{ 
    // all this weird members 
}; 

class Derived : public Base1, public Base2 
{ 
    // not so weird members 
}; 

int main() 
{ 
    Derived Wonder; 
    magicFunction(&Wonder); 
    return 0; 
} 

void magicFunction(Base2 *ptr) 
{ 
    if (Base1 *b1 = dynamic_cast<Base1 *>(ptr)) 
    b1->wonderFULL(); 
} 

Sin embargo WONDERFULL nunca se ejecuta debido a la imposibilidad de emitir ptr a B1. ¿Es posible realizar tal conversión?

+1

'-1' para publicar código que tiene un problema que impide la compilación del código en un área que está muy relacionada con el problema. – sbi

+1

Estoy de acuerdo con sbi. Esta muestra debe verse como http://www.ideone.com/dg0gc. 'magicFunction' debe ir antes de que' main', 'wonderFULL' se defina y se publique. – Bill

Respuesta

0

Por lo que entiendo de la forma en que algunos compiladores de C++ organizan la jerarquía de clases en la memoria, debería ser posible convertir de una clase base a otra, pero primero debe convertir a la clase derivada.

Por lo tanto lo que tendría que hacer algo como:

Base1* b1 = dynamic_cast<Derived*>(ptr); 

Esto arroja el puntero, dados ptr a la clase derivada, y luego se pone implícitamente fundido a su otro puntero de clase base.

Sin embargo, otra manera más fácil de hacer esto sería simplemente tener un método en la clase Base2 que devuelve un puntero Base1, y la clase derivada puede implementarlo sin ningún código complicado. (La misma función en Base2 puede simplemente devolver NULL si no desea una clase virtual pura).

7

Este

#include <iostream> 

class Base1 { 
public: 
    virtual void wonderFULL() = 0; 
}; 

class Base2 { 
public: 
    virtual ~Base2() {}          // added so the code compiles 
}; 

class Derived : public Base1, public Base2 { 
    virtual void wonderFULL() {std::cout << "wonderful\n";} // added so the code compiles 
}; 

void magicFunction(Base2 *ptr) { 
    if (Base1 *b1 = dynamic_cast<Base1 *>(ptr)) 
     b1->wonderFULL(); 
} 

int main() { 
    Derived Wonder; 
    magicFunction(&Wonder); 
    return 0; 
} 

impresiones wonderful para mí. Mi conclusión es que no está mostrando el código necesario para que su problema se reproduzca.

Tome (una copia de) su código actual y eliminando el código innecesario paso a paso destínelo hasta que obtenga un ejemplo compilable que contiene el problema (no necesita otros encabezados excepto desde el estándar lib). Es muy probable que encuentre el problema mientras lo hace. Sin embargo, si no lo hace, tiene el estuche de repro perfecto para volver aquí y preguntar.

+0

Este código no es lo que publicó el OP. (Tenga en cuenta que tiene una función virtual en Base2 que permite el dynamic_cast.) – Bill

+0

@Bill: Sí, por supuesto. De lo contrario, el compilador ni siquiera compilará el código.Ver mi nota al final de mi respuesta. – sbi

+0

+1, no se puede convertir a un puntero a clase A si la clase A no tiene funciones de miembro virtual. – sharptooth

2

Puedes lanzar la jerarquía y luego hacia abajo:

void magicFunction(Base2& ptr) 
{ 
    try 
    { 
     Derived& d = dynamic_cast<Derived&>(ptr); 
     Base1& b = dynamic_cast<Base1&>(d); 
     b.wonderFULL(); 
    } 
    catch(const std::bad_cast&) 
    { /* Cast failed */ } 
} 
+0

Eso no debería ser necesario con 'dynamic_cast'. Ver mi respuesta – sbi

+1

Documenta la intención. Si el compilador lo optimiza bien. Pero la documentación legible de entente humana es buena para mí. –

+0

(Debes @address ...) Si documentar el intento de esta manera es necesario está abierto al debate. La pregunta original ("¿Es posible emitir dinámicamente de una clase base a otra?") Debe tener una respuesta clara y simple. – sbi

2

Usted tiene algunos errores de sintaxis, pero el verdadero problema es dynamic_cast no funcionará correctamente si las clases de base no tienen al menos un virtuales función.

Si haces que parezca:

class Base2 
{ 
public: 
    virtual ~Base2() {} 
    // all this weird members 
}; 

Y a continuación, fijar sus otros errores: wonderFULL es privada, y nunca definido. magicFunction se declara después de su uso.

Luego todo works.

0

He encontrado el problema. No se trataba de dynamic_casts. Estaba revisando el objeto incorrecto que no fue heredado de la base abstracta. Gracias.

Cuestiones relacionadas