Dlaczego rozmiar klasy w c ++ zależy od publicznego / prywatnego statusu członków danych?

23

Z tego co wiem, wielkość klasy w c ++ zależy od następujących czynników -

  1. Rozmiar wszystkich niestatycznych elementów danych.
  2. Kolejność członków danych.
  3. Jeśli uzupełnianie bajtów jest włączone, czy nie.
  4. Rozmiar jego bezpośredniej klasy bazowej.
  5. Istnienie funkcji wirtualnych.
  6. Tryb dziedziczenia (dziedziczenie wirtualne).

Teraz utworzyłem 2 klasy, jak poniżej -

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

teraz po sprawdzeniu rozmiaru A i BI zobacz

  • rozmiar A: 16
  • rozmiar B: 16

moje założenie jest takie, że char c w klasie B mieści się w „otworze” pozostawionym w klasie A.

Ale, co mnie pomyliło, to poniższy scenariusz, w którym upubliczniam członków

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

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

Teraz rozmiar się zmienia

  • rozmiar A: 16
  • rozmiar B: 20

Nie potrafię zrozumieć przyczyny tej różnicy.

J.DOE
źródło
1
Dlaczego rozmiar klasy w c ++ zależy od publicznego / prywatnego statusu członków danych? - Nie ma. Są to szczegóły implementacji zależne od kompilatora.
PaulMcKenzie
1
Jakiego kompilatora używasz?
Romen,
2
@PaulMcKenzie Właściwie to robi. Standardowe mandaty członków z tym samym dostępem są grupowane razem, co powoduje zmianę strategii wypełniania kompilatora.
NathanOliver
@ NathanOliver-ReinstateMonica, nie wiedziałem o tym. Czy masz przypadkiem odniesienie do odpowiedniej sekcji?
R Sahu,
@RSahu Patrząc na to, by teraz mocno udzielić mojej odpowiedzi.
NathanOliver

Odpowiedzi:

8

Itanium ABI korzysta z definicji POD POD C ++ 03, aby zdefiniować klasy, które są „POD do celów układu”. Posiadanie prywatnych członków danych dyskwalifikuje klasę z bycia agregatem, a zatem POD w C ++ 03:

Struktura POD jest strukturą zagregowaną, która nie ma niestatycznych elementów danych typu non-POD-struct, non-POD-union (lub tablica takich typów) lub odwołania i nie ma zdefiniowanego przez użytkownika operatora przypisania kopii i nie ma destruktor zdefiniowany przez użytkownika.

Bycie klasą POD uniemożliwia ponowne użycie wyściółki ogona :

Dsize, nvsize i nvalign tych typów są zdefiniowane jako ich zwykłe rozmiary i wyrównanie. Te właściwości mają znaczenie tylko w przypadku niepustych typów klas używanych jako klasy podstawowe. Ignorujemy dopełnianie ogona dla POD, ponieważ wczesna wersja standardu nie pozwalała nam używać go do niczego innego, a ponieważ czasami pozwala na szybsze kopiowanie tego typu.

Tak więc, w twoim pierwszym przykładzie, Anie jest POD dla celów układu i jego wyściółka ogona może być użyta B::c, ale w drugim przykładzie jest POD, a jego wyściółki ogona nie można ponownie użyć.

TC
źródło