Puntatore alla classe base
-
27-09-2019 - |
Domanda
Se ho le seguenti classi:
class A
{
...
}
class B
{
...
}
class C : public A, public B
{
...
}
e da qualche parte a rilevare che il puntatore di classe B
che ho effettivamente punti ad un C
classe, ma una funzione richiede un puntatore alla classe A
, cosa posso fare per ottenere che il puntatore alla classe A
?
Soluzione
Se si sa per certo che hai un B*
che punta a un oggetto C
, è possibile utilizzare un paio di static_cast
s:
B* bp = new C();
C* cp = static_cast<C*>(bp);
A* ap = static_cast<A*>(cp);
L'unico modo per lanciare in tutta la gerarchia di ereditarietà è quello di utilizzare dynamic_cast
, che richiede che il tipo è polimorfico (cioè, la classe deve avere almeno una funzione membro virtuale; dal momento che i tuoi distruttori classe di base dovrebbero essere virtual
, questo di solito non è un problema):
B* bp = new C();
A* ap = dynamic_cast<A*>(bp);
dynamic_cast
ha l'ulteriore vantaggio che se viene a mancare (che è, se bp
in realtà non puntano a C
), restituisce NULL. Essa ha lo svantaggio di un costo delle prestazioni leggera (static_cast
è effettivamente libero in fase di esecuzione).
Altri suggerimenti
Il codice
class A
{
};
class B
{
};
class C : public A, public B
{
};
int main() {
C c;
A *a = &c;
}
è valida in quanto C è già una A, quindi la cessione è valida.
Se C eredita da una come lei hanno dimostrato, poi un C * puntatore dovrebbe essere implicitamente convertibile in una * puntatore A. E 'possibile che tu non abbia incluso la dichiarazione di classe C, in modo che il compilatore non è a conoscenza di questa relazione di ereditarietà? O che v'è in realtà una relazione di ereditarietà diverso rispetto a quello indicato nella tua domanda? Alcuni codice sarebbe utile nella diagnosi di questo problema.
Modifica
Sulla base della versione aggiornata della tua domanda:
// 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
}