Por que o tamanho da classe em c ++ depende do status público / privado dos membros de dados?

23

Pelo que sei, o tamanho de uma classe em c ++ depende dos fatores abaixo -

  1. Tamanho de todos os membros de dados não estáticos.
  2. Ordem dos membros dos dados.
  3. Se o preenchimento de bytes estiver ativado ou não.
  4. Tamanho de sua classe base imediata.
  5. A existência de funções virtuais.
  6. Modo de herança (herança virtual).

Agora eu criei 2 classes como abaixo -

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;  
};

agora, verificando o tamanho de A e BI, veja

  • tamanho de A: 16
  • tamanho de B: 16

minha suposição é que o char c na classe B é acomodado no "buraco" deixado na classe A.

Mas, o que me confunde é o cenário abaixo, em que eu publico os membros

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

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

Agora o tamanho se torna

  • tamanho de A: 16
  • tamanho de B: 20

Não consigo entender o motivo dessa diferença.

J.DOE
fonte
11
Por que o tamanho da classe em c ++ depende do status público / privado dos membros de dados? - Isso não acontece. Esses são detalhes de implementação dependentes do compilador.
PaulMcKenzie
11
Então, qual compilador você está usando?
Romen
2
@PaulMcKenzie Na verdade, sim. Os membros de mandatos padrão com o mesmo acesso são agrupados de forma que as alterações sejam alteradas na estratégia de preenchimento do compilador.
NathanOliver
@ NathanOliver-ReinstateMonica, eu não sabia disso. Você tem uma referência à seção relevante à mão por acaso?
R: Sahu
@RSahu Olhando para colocar minha resposta apertada agora.
NathanOliver

Respostas:

8

O Itanium ABI usa a definição de POD C ++ 03 para definir classes que são "POD para fins de layout". Ter membros de dados privados desqualifica uma classe de ser um agregado e, portanto, um POD no C ++ 03:

Uma estrutura POD é uma classe agregada que não possui membros de dados não estáticos do tipo estrutura não POD, união não POD (ou matriz de tais tipos) ou referência e não possui operador de atribuição de cópia definido pelo usuário e nenhum destruidor definido pelo usuário.

Ser uma classe POD desativa a reutilização do preenchimento da cauda :

O dsize, nvsize e nvalign desses tipos são definidos como tamanho e alinhamento comuns. Essas propriedades são importantes apenas para os tipos de classe não vazios que são usados ​​como classes base. Ignoramos o preenchimento de cauda para PODs porque uma versão inicial do padrão não nos permite usá-lo para mais nada e porque às vezes permite cópias mais rápidas do tipo.

Portanto, no seu primeiro exemplo, Anão é um POD para fins de layout e seu preenchimento de cauda pode ser usado B::c, mas no segundo exemplo, é um POD e seu preenchimento de cauda não pode ser reutilizado.

TC
fonte