Warum hängt die Klassengröße in c ++ vom öffentlichen / privaten Status der Datenelemente ab?

23

Soweit ich weiß, hängt die Größe einer Klasse in C ++ von den folgenden Faktoren ab:

  1. Größe aller nicht statischen Datenelemente.
  2. Reihenfolge der Datenmitglieder.
  3. Ob das Auffüllen von Bytes aktiviert ist oder nicht.
  4. Größe seiner unmittelbaren Basisklasse.
  5. Die Existenz virtueller Funktionen.
  6. Vererbungsmodus (virtuelle Vererbung).

Jetzt habe ich 2 Klassen wie folgt erstellt -

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

Jetzt zur Überprüfung der Größe von A und BI siehe

  • Größe von A: 16
  • Größe von B: 16

Ich gehe davon aus, dass das Zeichen in Klasse B in dem in Klasse A verbleibenden "Loch" untergebracht ist.

Was mich jedoch verwirrt hat, ist das folgende Szenario, in dem ich die Mitglieder öffentlich mache

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

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

Jetzt wird die Größe

  • Größe von A: 16
  • Größe von B: 20

Ich kann den Grund für diesen Unterschied nicht verstehen.

J. DOE
quelle
1
Warum hängt die Klassengröße in c ++ vom öffentlichen / privaten Status der Datenelemente ab? - Das tut es nicht. Dies sind compilerabhängige Implementierungsdetails.
PaulMcKenzie
1
Welchen Compiler verwenden Sie?
Romen
2
@PaulMcKenzie Eigentlich tut es. Die Standardmandatsmitglieder mit demselben Zugriff werden so gruppiert, dass sich die Auffüllstrategie des Compilers ändert.
NathanOliver
@ NathanOliver-ReinstateMonica, das wusste ich nicht. Haben Sie zufällig einen Verweis auf den entsprechenden Abschnitt zur Hand?
R Sahu
@RSahu Ich schaue nach, um meine Antwort jetzt genau zu formulieren.
NathanOliver

Antworten:

8

Das Itanium ABI verwendet die C ++ 03-Definition von POD , um Klassen zu definieren, die "POD für Layoutzwecke" sind. Wenn private Datenelemente vorhanden sind, wird eine Klasse als Aggregat und damit als POD in C ++ 03 disqualifiziert:

Eine POD-Struktur ist eine Aggregatklasse, die keine nicht statischen Datenelemente vom Typ Nicht-POD-Struktur, Nicht-POD-Vereinigung (oder Array solcher Typen) oder Referenz enthält und keinen benutzerdefinierten Kopierzuweisungsoperator und keine hat benutzerdefinierter Destruktor.

Als POD-Klasse wird die Wiederverwendung von Heckpolstern deaktiviert :

Die Größen dsize, nvsize und nvalign dieser Typen werden als ihre normale Größe und Ausrichtung definiert. Diese Eigenschaften sind nur für nicht leere Klassentypen von Bedeutung, die als Basisklassen verwendet werden. Wir ignorieren das Tail Padding für PODs, weil wir es in einer frühen Version des Standards nicht für andere Zwecke verwenden konnten und weil es manchmal ein schnelleres Kopieren des Typs ermöglicht.

In Ihrem ersten Beispiel Ahandelt es sich also nicht um einen POD für Layoutzwecke, und die Schwanzpolsterung kann verwendet B::cwerden. In Ihrem zweiten Beispiel handelt es sich jedoch um einen POD, und die Heckpolsterung kann nicht wiederverwendet werden.

TC
quelle