Sé que el diseño de memoria de la herencia múltiple no está definido, por lo que no debería confiar en él. Sin embargo, ¿puedo confiar en un caso especial? Es decir, una clase tiene una sola superclase "real". Todos los demás son "clases vacías", es decir, clases que no tienen campos ni métodos virtuales (es decir, solo tienen métodos no virtuales). En este caso, estas clases adicionales no deberían agregar nada al diseño de la memoria de la clase. (Más concisamente, en la redacción de C++ 11, la clase tiene diseño estándar)C++ Diseño de memoria de herencia múltiple con "Clases vacías"
¿Puedo inferir que todas las superclases no tendrán desplazamiento? Ej .:
#include <iostream>
class X{
int a;
int b;
};
class I{};
class J{};
class Y : public I, public X, public J{};
int main(){
Y* y = new Y();
X* x = y;
I* i = y;
J* j = y;
std::cout << sizeof(Y) << std::endl
<< y << std::endl
<< x << std::endl
<< i << std::endl
<< j << std::endl;
}
Aquí, Y
es la clase con X
siendo la única clase base real. La salida del programa (cuando se compila en Linux con g ++ 4,6) es como sigue:
0x233f010
0x233f010
0x233f010
0x233f010
Como llegué a la conclusión, no hay poi nter ajuste. Pero esta implementación es específica o puedo confiar en ella. Es decir, si recibo un objeto del tipo I
(y sé que solo existen estas clases), ¿puedo usar un reinterpret_cast
para convertirlo al X
?
Espero que pueda confiar en él porque la especificación dice que el tamaño de un objeto debe ser al menos un byte. Por lo tanto, el compilador no puede elegir otro diseño. Si tuviera el formato I
y J
detrás de los miembros de X
, entonces su tamaño sería cero (porque no tienen miembros). Por lo tanto, la única opción razonable es alinear todas las súper clases sin compensación.
¿Estoy correcto o estoy jugando con el fuego si uso reinterpret_cast desde I
hasta X
aquí?
El diseño de la memoria de la herencia, uno o varios, bases vacías o no, no está definido. –
Diría que estás jugando con fuego, porque estás tratando de crear un constructo muy extraño que sin duda causará dolor y sufrimiento a cualquiera que tenga que entenderlo en el futuro, incluso si no se rompe cuando actualizas tu compilador! – Rook
afortunadamente, sus declaraciones ya no son correctas en C++ 11, vea la respuesta :) – gexicide