¿Por qué el tamaño de la clase en c ++ depende del estado público / privado de los miembros de datos?

23

Por lo que sé, el tamaño de una clase en c ++ depende de los siguientes factores:

  1. Tamaño de todos los miembros de datos no estáticos.
  2. Orden de los miembros de datos.
  3. Si el relleno de bytes está habilitado o no.
  4. Tamaño de su clase base inmediata.
  5. La existencia de funciones virtuales.
  6. Modo de herencia (herencia virtual).

Ahora he creado 2 clases de la siguiente manera:

class A{
    int a;
    short s;
    int b;
    char d;
};// kept a char at last on purpose to leave a "hole"

class B : public A{
    char c;  
};

ahora en comprobar el tamaño de A y BI ver

  • tamaño de A: 16
  • tamaño de B: 16

mi suposición es que el carbón en la clase B se acomoda en el "agujero" que queda en la clase A.

Pero, lo que me confunde es el siguiente escenario en el que hago públicos a los miembros

class A{
    public:
    int a;
    short d;
    int b;
    char s;
};

class B : public A{
    public:
    char c;
};

Ahora el tamaño se convierte

  • tamaño de A: 16
  • tamaño de B: 20

Parece que no puedo entender la razón de esta diferencia.

J.DOE
fuente
1
¿Por qué el tamaño de la clase en c ++ depende del estado público / privado de los miembros de datos? No lo hace. Esos son detalles de implementación dependientes del compilador.
PaulMcKenzie
1
Entonces, ¿qué compilador estás usando?
Romen
2
@PaulMcKenzie En realidad lo hace. Los miembros de mandatos estándar con el mismo acceso se agrupan, por lo que cambiar eso cambiará la estrategia de relleno del compilador.
NathanOliver el
@ NathanOliver-ReinstateMonica, no lo sabía. ¿Tiene alguna referencia a la sección relevante a mano por casualidad?
R Sahu
@RSahu Buscándolo para poner mi respuesta apretada ahora.
NathanOliver el

Respuestas:

8

El Itanium ABI utiliza la definición C ++ 03 de POD para definir clases que son "POD para propósitos de diseño". Tener miembros de datos privados descalifica a una clase de ser un agregado y, por lo tanto, POD en C ++ 03:

Un POD-struct es una clase agregada que no tiene miembros de datos no estáticos de tipo non-POD-struct, non-POD-union (o array de tales tipos) o referencia, y no tiene operador de asignación de copia definido por el usuario y no destructor definido por el usuario.

Ser una clase POD deshabilita la reutilización del relleno de la cola :

Los tamaños dsize, nvsize y nvalign de estos tipos se definen como su tamaño y alineación normales. Estas propiedades solo son importantes para los tipos de clase no vacíos que se utilizan como clases base. Ignoramos el relleno de cola para los POD porque una versión anterior del estándar no nos permitía usarlo para nada más y porque a veces permite una copia más rápida del tipo.

Por lo tanto, en su primer ejemplo, Ano es un POD para fines de diseño y su relleno de cola se puede usar B::c, pero en su segundo ejemplo, es un POD y su relleno de cola no se puede reutilizar.

TC
fuente