Garanzie indirizzo di baseclass in C++?
-
24-09-2019 - |
Domanda
In struct in C, sono la garanzia che:
struct Foo { ... };
struct Bar {
Foo foo;
...
}
Bar bar;
assert(&bar == &(bar.foo));
Ora, in C++, se ho:
class Foo { ... };
class Bar: public Foo, public Other crap ... {
...
}
Bar bar;
assert(&bar == (Foo*) (&bar)); // is this guaranteed?
Se è così, mi puoi dare un riferimento (come "Il Linguaggio di Programmazione C++, pagina xyz")?
Grazie!
Soluzione
Non v'è alcuna garanzia. Dalla C ++ 03 standard (10/3, class.derived):
L'ordine in cui i sottoggetti classe di base sono allocati nell'oggetto massima derivazione (1.8) è specificato.
Altri suggerimenti
Anche se il layout per le classi di base è non è garantito nel modo in cui ti sembra di essere stato il pensiero (e anche se non ci sono più garanzie per i soci), questo è garantito:
Bar bar;
assert(&bar == (Foo*) (&bar));
Perché il cast utilizza un static_cast (per 5.4) che permette di convertire il &bar
correttamente, e il confronto tra puntatore-a-base e puntatore-a-derivato convertire allo stesso modo.
Questo, tuttavia, non sarebbe garantita:
Bar bar;
void* p1 = &bar;
void* p2 = (Foo*)&bar;
assert(p1 == p2); // not guaranteed
Non immagino che sia, non so il motivo per cui avrebbe bisogno di essere.
Ho una domanda relativa.
se avete eredità diamante:
class Base(){ virtual void AFunc(){} };
class A:Base{};
class B:Base{void AFunc(){} }
class Test:A,B{};
Base * b = (Base*)new Test;
b->AFunc();
lascia supporre che la struttura di memoria è di base: A: B: Test,
Nota al punto di chiamare, tutto il compilatore sa è l'indirizzo di inizio dell'oggetto, e AFunc si aspetta di essere relativamente all'inizio dell'oggetto B, questi due indirizzi non sarà lo stesso! così come funziona?
come se B è stato di tipo B, i due indirizzi sarebbero lo stesso ...