2011-09-15 21 views

risposta

9

No. Questo non è possibile (casting diretto da A* a B*).

Poiché l'indirizzo di A e B si trova in posizioni diverse in class C. Pertanto, il cast non sarà sempre sicuro e probabilmente potresti cadere nel comportamento inatteso . Demo.

Il casting deve sempre passare attraverso class C. per esempio.

A* pa = new C(); 
B* pb = static_cast<C*>(pa); 
        ^^^^ go through class C 

Demo

+0

Grazie. Il comportamento inaspettato è esattamente quello che ho avuto) – Andrew

+0

Ma non riesco a capire perché dynamic_cast è andato bene – Andrew

+0

@Andrew, 'dynamic_cast ' è anche valido e funzionerà (a patto che le classi siano polimorfiche); perché 'C' è in realtà una sottoclasse di' A'. Tuttavia, in questo caso 'static_cast ' sarà un'idea migliore come succede al momento della compilazione. – iammilind

2

Sì, si deve prima static_cast oggetto da C *, allora si può static_cast di nuovo per B (sebbene quest'ultimo cast non sia necessario, poiché è una conversione standard). Non sono sicuro che se l'oggetto static_cast direttamente su B funzioni, prova a vedere se ottieni errori del compilatore. reinterpret_cast L'inserimento di un oggetto in B causerebbe un arresto anomalo del runtime, poiché A e B avrebbero indirizzi diversi se entrambi non sono vuoti.

Modifica Dopo aver modificato la domanda, non è più possibile fare ciò che si desidera. È necessario conoscere il percorso corretto su e giù dall'albero di ereditarietà, poiché il cast in uno scenario con ereditarietà multiple con classi non vuote implica spostamenti nel puntatore.

+0

Vedere la mia modifica (Importante) – Andrew

0

Fintanto che l'oggetto è derivato da B, è sempre possibile eseguire il cast dell'oggetto su B. E ovviamente, è possibile chiamare solo i metodi definiti nell'interfaccia B, poiché il puntatore virtuale può accedere solo al metodo definito da B nella tabella virtuale.

8

La strada da percorrere da qualsiasi tipo a qualsiasi altro è dynamic_cast. Ma richiede che l'oggetto sia polimorfo. In generale questo richiede una v-table essere associato sia A e B, quindi: se A e B hanno almeno una funzione virtuale e RTTI non si disattivano,

A* pa1 = new C; 
A* pa2 = new A; 

B* pb1 = dynamic_cast<B*>(pa1); 
B* pb2 = dynamic_cast<B*>(pa2); 

provocherà PB2 per essere nullo e pb1 per puntare alla parte B dell'oggetto che contiene * pa1 come sua parte A. (Il fatto che sia C o qualunque altro derivato da quelle due basi non ha importanza).

In caso contrario, in cui tutte le necessità di essere statiche, è necessario passare attraverso C

B* pb = static_cast<B*>(static_cast<C*>(pa)); 

Nota che static_cast<B*>(pA) non può compilare, essendo A e B tra loro non correlati.

Problemi correlati