Ponteiro para a classe base
-
27-09-2019 - |
Pergunta
Se eu tiver as seguintes aulas:
class A
{
...
}
class B
{
...
}
class C : public A, public B
{
...
}
e em algum lugar eu detecto que o ponteiro da aula B
que eu realmente apoio para uma aula C
, mas uma função requer um ponteiro para a classe A
, o que posso fazer para conseguir esse ponteiro para a aula A
?
Solução
Se você sabe com certeza que tem um B*
Isso aponta para um C
objeto, você pode usar um par de static_cast
s:
B* bp = new C();
C* cp = static_cast<C*>(bp);
A* ap = static_cast<A*>(cp);
A única maneira de lançar a hierarquia de herança é usar dynamic_cast
, que exige que o tipo seja polimórfico (ou seja, sua classe deve ter pelo menos uma função de membro virtual; Uma vez que seus destruidores de classe base devem ser virtual
, Isso geralmente não é um problema):
B* bp = new C();
A* ap = dynamic_cast<A*>(bp);
dynamic_cast
tem o benefício adicional de que, se falhar (ou seja, se bp
na verdade não aponta para um C
), ele retorna nulo. Tem a desvantagem de um pequeno custo de desempenho (static_cast
é efetivamente livre em tempo de execução).
Outras dicas
O código
class A
{
};
class B
{
};
class C : public A, public B
{
};
int main() {
C c;
A *a = &c;
}
é válido, pois C já é um A, então a tarefa é válida.
Se C herdar de A como você mostrou, um ponteiro C* deve ser implicitamente conversível para um ponteiro A*. É possível que você não tenha incluído a declaração da classe C, para que o compilador não esteja ciente dessa relação de herança? Ou que existe realmente um relacionamento de herança diferente do que a dada em sua pergunta? Algum código seria útil para diagnosticar esse problema.
Editar
Com base na versão atualizada da sua pergunta:
// 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
}