Puntero a la clase base
-
27-09-2019 - |
Pregunta
Si tengo las siguientes clases:
class A
{
...
}
class B
{
...
}
class C : public A, public B
{
...
}
y en algún lugar detecto que el puntero de la clase B
que tengo en realidad apunta a una C
clase, pero una función requiere un puntero a A
clase, ¿qué puedo hacer para conseguir que el puntero a A
clase?
Solución
Si sabe con certeza que usted tiene un B*
que apunta a un objeto C
, se puede utilizar un par de static_cast
s:
B* bp = new C();
C* cp = static_cast<C*>(bp);
A* ap = static_cast<A*>(cp);
La única forma de molde a través de la jerarquía de herencia es utilizar dynamic_cast
, que requiere que el tipo es polimórfico (es decir, su clase debe tener al menos una función miembro virtual; ya que sus destructores de la clase base debe ser virtual
, esto normalmente no es un problema):
B* bp = new C();
A* ap = dynamic_cast<A*>(bp);
dynamic_cast
tiene la ventaja añadida de que si se produce un error (es decir, si bp
en realidad no apuntan a un C
), devuelve NULL. Tiene el inconveniente de un costo de rendimiento ligero (static_cast
es efectivamente libre en tiempo de ejecución).
Otros consejos
El código
class A
{
};
class B
{
};
class C : public A, public B
{
};
int main() {
C c;
A *a = &c;
}
es válida desde C ya es un A, por lo que la asignación es válida.
Si C hereda de una medida que han demostrado, a continuación, un C * puntero debe ser convertir implícitamente a una A * puntero. ¿Es posible que no se ha incluido la declaración de la clase C, por lo que el compilador no es consciente de esta relación de herencia? O que en realidad hay una relación de herencia diferente a la dada en su pregunta? Parte del código sería de gran ayuda en el diagnóstico de este problema.
Editar
Sobre la base de la versión actualizada de su pregunta:
// Converts b to type A*, but only if it is actually
// of type C; otherwise, returns NULL
A* convertBtoAviaC(B* b) {
C* c = dynamic_cast<C*>(b);
return c; // note may be NULL, if b is not a C
}