quindi è impossibile per downcast utilizzando static_cast
con l'ereditarietà virtuale, ma come è possibile effettuare le seguenti operazioni upcast:Come può essere usato static_cast con l'ereditarietà virtuale?
class Base {...};
class Derived : public virtual Base {...};
...
Derived *d = new Derived();
Base *b = static_cast<Base*>(d);
Struttura memoria dell'oggetto:
[ derived part | base part ]
So che upcasting è considerato "sicuro", ma come può il compilatore conoscere l'offset del sottomodulo di base in fase di compilazione, quando l'ereditarietà è virtuale? Il static_cast
utilizza lo vtable
?
Ciò è particolarmente confusa quando abbiamo qualcosa di simile (si noti che non è virtuale):
class Third : public Derived {...};
...
Derived *d = new Third(); // non-virtual upcast, no offset will be added
Base *b = static_cast<Base*>(d);
Questa volta ho usato la stessa linea static_cast
, ma l'offset per il sub-oggetto Base
è diverso!
Struttura memoria dell'oggetto:
[ derived part | third part | base part ]
Così come può essere determinato al momento della compilazione, se dipende dal tipo dinamico effettivo dell'oggetto d
punti?
Questo di solito è il caso da quello che so, che gli offset sono memorizzati nel vtable. Tuttavia questo non risponde alla domanda su come è fatto staticamente in fase di compilazione. Se osservi i due casi che ho fornito, solleva la questione di quale vtable ha l'offset corretto? Quale dovrebbe essere il compilatore, Dertable's vtable o Third's vtable? Chiaramente i 2 offset nei vtables sono diversi e la scelta del vtable corretto dipende dal tipo di runtime di s. Ecco perché non riesco a capire come sia fatto staticamente. –
Lo "statico" in 'static_cast' non significa che sia fatto in fase di compilazione! Significa semplicemente che il compilatore può determinare in modo statico dove trovare le informazioni in fase di compilazione: ad esempio, sa dove cercare l'offset nel vtable o dove si trova il puntatore incorporato alla base (a seconda di come l'ereditarietà virtuale è implementato). Non andrà alla ricerca di una corrispondenza di qualche classe nel vtable come fa 'dynamic_cast'. –
Quindi stai dicendo che static_cast ha un aspetto dinamico, vedo. In base a tale logica, perché non è possibile che static_cast esegua downcasting nell'ereditarietà virtuale? –