class B : public A { };
A* p1 = new B; // B may be larger than A :OK [Line 1]
B* p2 = new A; // B may be larger than A :Not OK [Line 2]
No entiendo lo que quiere decir el autor comentando en las líneas 1 y 2.
Por qué no podemos hacer en la línea 2?
class B
se deriva de class A
, que - desde la perspectiva de las variables miembro que contiene - significa que tiene todo lo que una tiene y todo lo que opta por sumarse. En su código simple, B no ha agregado nada, pero si tuviera miembros adicionales de datos, claramente requeriría más memoria para almacenar que el tipo más simple A
. Si agrega una función de miembro virtual donde A no tenía ninguno, se podría esperar que el compilador agregue un puntero en B que registre la dirección de la tabla de despacho virtual que enumera las direcciones de sus funciones de miembro virtual
. El compilador también puede agregar relleno si así lo desea.
En consecuencia, el caso general es que el tamaño de una clase derivada es >=
del tamaño de su clase base.
A* p1 = new B; // B may be larger than A :OK [Line 1]
Aquí, sin embargo la cantidad de espacio necesario B
realidad está siendo asignado del montón/libre de la tienda, y la dirección de esa memoria almacenada en p1
. Si B
es más grande que A
, no hace ninguna diferencia, eso está en otro lugar de todos modos, la clave es que un B*
está garantizado para poder almacenarse en un A*
.
B* p2 = new A; // B may be larger than A :Not OK [Line 2]
Aquí, una nueva A
se está creando en el montón, pero el programador está tratando de decirle al compilador que hay un B
en esa dirección. El compilador no lo creerá (a menos que sea forzado); simplemente obtendrá un error de tiempo del compilador. Si lo hace obligar al compilador (por ejemplo, p2 = (B *) (nueva A) ) to treat the memory address in
p2 as if it were an
B , then it may later try to access additional data it expects to be part of any
B which simply doesn't exist in any
A`: Miembros de datos adicionales, punteros de despacho virtuales, etc ..
De hecho, creo que 'A' puede ser más grande que' B', debido a la optimización de la clase base vacía y algunos diseños ABI extraños. –