2016-01-25 13 views
5

Supponiamo che io sono:Devo aspettarmi che gli upcast e i downcast nell'ereditarietà singola non regolino il puntatore?

class Base { 
public: 
    virtual void Nothing() {} 
}; 
class MiddleDerived : public Base { 
    virtual void Nothing() {} 
}; 
class Derived : public MiddleDerived { 
    virtual void Nothing() {} 
}; 

e il mio codice va in questo modo:

Derived* object = new Derived(); 
Base* base = object; //implicit conversion here 

void* derivedVoid = object; 
void* baseVoid = base; 

Devo aspettare che baseVoid == derivedVoid?

So che la maggior parte delle implementazioni funziona in questo modo ma è garantita?

+0

Considerare la sostituzione di "avvocato linguistico" per "portabilità"? – Bathsheba

+0

Mentre formulavate la domanda (anziché l'esempio) avete lasciato aperta la possibilità che la classe base potesse non avere alcun metodo virtuale (mentre alcune classi derivate lo fanno). Potrebbe ancora essere una "eredità singola" ma i puntatori non sarebbero ** uguali. Per il tuo ** esempio **, non sono un avvocato linguistico abbastanza bravo per sostenere la mia convinzione che sia vero solo nella pratica comune, non promessa dallo standard. – JSF

+0

Penso che questo dovrebbe funzionare ma non penso che ci sia un layout standard per le classi non POD. – NathanOliver

risposta

2

Quello che "si aspetta" può essere diverso da quello garantito.

A static_cast in alto o in basso una catena di eredità può modificare l'indirizzo.

L'esempio canonico in cui ciò si verifica in pratica è dove una classe base non è polimorfica e una classe derivata introduce una funzione virtuale, che con molti compilatori introduce un puntatore vtable all'inizio di ogni oggetto derivato.

2

Penso che la parte della norma che si occupa di questo è §5.2.9 (13)

Quale afferma (in poche parole) che un T * cast un void * e poi di nuovo ad un T * deve riferirsi allo stesso oggetto.

Tuttavia non c'è alcuna indicazione L'indirizzo di Derived deve essere uguale all'indirizzo Base.

Quindi la mia risposta sarebbe "no - codice che si aspetta questa equivalenza è malformato invitando comportamento indefinito".

Problemi correlati