О единственном случае, когда объект базового класса не будет иметь тот же адрес, что и его объект подкласса, это когда задействовано множественное наследование.
В приведенном выше примере память, вероятно, выглядит следующим образом:
/ --------- \
/ | x | > This is the Foo portion of bar
This is the whole Bar object < --------- /
\ | y |
\ ---------
Оба вида объекта имеют одинаковую начальную точку, поэтому указатель на оба вида будет иметь одинаковое значение.
При множественном наследовании все усложняется. Скажем, у вас есть:
struct Foo1{ int x; };
struct Foo2{ int y; };
struct Bar : public Foo1, public Foo2 { int z; };
Bar bar;
Теперь память должна быть выложена примерно так:
/ --------- \
/ | x | > This is the Foo1 portion of bar
/ --------- / \
This is the whole Bar object < | y | > This is the Foo2 portion of bar
\ --------- /
\ | z |
\ ---------
Так что &bar
и (Foo1*)&bar
будут иметь одно и то же значение, в то время как (Foo2*)&bar
будет иметь другое значение, поскольку часть Foo2
объекта начинается с более высокого адреса.