Ich habe mich gefragt, wie groß ein Objekt einer leeren Klasse sein könnte . Es könnte sicherlich nicht 0 Bytes sein, da es möglich sein sollte, wie jedes andere Objekt darauf zu verweisen und darauf zu zeigen. Aber wie groß ist ein solches Objekt?
Ich habe dieses kleine Programm benutzt:
#include <iostream>
using namespace std;
class Empty {};
int main()
{
Empty e;
cerr << sizeof(e) << endl;
return 0;
}
Die Ausgabe, die ich sowohl auf Visual C ++ - als auch auf Cygwin-g ++ - Compilern erhielt, war 1 Byte ! Dies war für mich ein wenig überraschend, da ich erwartet hatte, dass es die Größe des Maschinenworts hat (32 Bit oder 4 Bytes).
Kann jemand erklären, warum die Größe von 1 Byte? Warum nicht 4 Bytes? Ist dies auch vom Compiler oder der Maschine abhängig? Kann jemand einen schlüssigeren Grund dafür angeben, warum ein leeres Klassenobjekt nicht die Größe 0 Bytes hat?
Antworten:
In den häufig gestellten Fragen zu C ++ - Stil und Technik von Bjarne Stroustrup wird angegeben , dass die Größe ungleich Null ist: "Um sicherzustellen, dass die Adressen von zwei verschiedenen Objekten unterschiedlich sind." Und die Größe kann 1 sein, da die Ausrichtung hier keine Rolle spielt, da es nichts zu sehen gibt.
quelle
new
; Wenn der Speicherplatz zugewiesen wird, muss eine andere Zuweisung eine andere Adresse haben. Und so weiter. In der leeren Klasse ist nicht unbedingt ein Zeiger enthalten. Möglicherweise gibt es Zeiger auf die Variablen (oder Referenzen oder lokale / Stapelzuordnungen), aber sie haben keine Größe von Null und sie müssen nicht unbedingt Zeigergröße haben.Der Standard besagt, dass alle am meisten abgeleiteten Objekte sizeof ()> = 1 haben:
quelle
Das ist wirklich ein Implementierungsdetail. Vor langer Zeit dachte ich, es könnten null oder tausend Bytes sein, was keinen Einfluss auf die Sprachspezifikation hat. Nach Betrachtung des Standards (Abschnitt 5.3.3) wird
sizeof
jedoch definiert, dass immer einer oder mehrere zurückgegeben werden, egal was passiert .Dies ist unter anderem erforderlich, damit Sie Arrays von Objekten und Zeigern auf diese verarbeiten können. Wenn Ihre Elemente die Größe Null haben könnten,
&(array[0])
wäre dies identisch mit&(array[42])
, was Ihre Verarbeitungsschleifen in jeder Hinsicht verwüsten würde.Der Grund, warum es möglicherweise kein Maschinenwort ist, besteht darin, dass es keine Elemente enthält, die tatsächlich erfordern, dass es an einer Wortgrenze (z. B. einer Ganzzahl) ausgerichtet wird. Wenn Sie beispielsweise
char x; int y;
innerhalb der Klasse platzieren, taktet mein GCC sie mit acht Bytes (da das zweite int in dieser Implementierung ausgerichtet sein muss).quelle
Es gibt eine Ausnahme: Arrays mit einer Länge von 0
quelle
c
,&c[M] == &c[N]
für jedenM
undN
(Klirren ++ 4.1).Obwohl es nicht erforderlich ist, einer leeren Klasse Speicher zuzuweisen, sondern um Objekte aus leeren Klassen zu erstellen, weist der Compiler den minimalen Speicher zu, der zugewiesen werden kann, nämlich 1 Byte. Auf diese Weise kann der Compiler zwei Objekte derselben leeren Klasse eindeutig unterscheiden und die Adresse des Objekts einem Zeiger des leeren Klassentyps zuweisen.
quelle
Ich denke, es könnte hilfreich sein, auf eine Antwort zu verlinken, die dies auch gut erklärt. Es ist etwa
boost::compressed_pair
von Logan Capaldo .quelle
Dies kann Ihnen helfen :-) http://bytes.com/topic/c/insights/660463-sizeof-empty-class-structure-1-a
quelle
Die Zuweisung von 1 Byte für eine leere Klasse ist vom Compiler abhängig. Compiler müssen sicherstellen, dass sich Objekte an verschiedenen Speicherorten befinden, und sie müssen einem Objekt eine Speichergröße ungleich Null zuweisen. Hören Sie sich hier Notizen zu diesem Thema an: http://listenvoice.com/listenVoiceNote.aspx?id=27
Obwohl Compiler einer leeren Klasse eine Größe ungleich Null zuweisen, führen sie auch Optimierungen durch, wenn neue Klassen aus leeren Klassen abgeleitet werden. Informieren Sie sich über die Optimierung der leeren Basis in den Interviewfragen von ListenVoice zur C ++ - Programmierung.
quelle
Der Grund für eine Klasse ohne Datenelemente mit einer Größe von 1 Byte ist, dass dieser * starke Text * im Speicher gespeichert werden muss, damit eine Referenz oder ein Zeiger auf das Objekt dieser Klasse verweisen kann
quelle
leere Klasse - Diese Klasse enthält keinen Inhalt.
Jede Klasse, die nicht leer ist, wird durch ihren Inhalt im Speicher dargestellt.
Wie wird nun die leere Klasse im Speicher dargestellt? Da es keinen Inhalt gibt, der seine Existenz im Speicher nicht zeigen kann, aber eine Klasse vorhanden ist, ist es obligatorisch, seine Präsenz im Speicher zu zeigen. Um die Präsenz einer leeren Klasse im Speicher anzuzeigen, ist 1 Byte erforderlich.
quelle
Ich denke, das ist so, weil 1 Byte die kleinste Speichereinheit ist, die als Platzhalter verwendet werden kann, und keine Größe von Null angegeben werden kann, da es nicht möglich ist, ein Array von Objekten zu erstellen.
und die Sache, die Sie sagten "Das war ein wenig überraschend für mich, da ich erwartet hatte, dass es die Größe des Maschinenworts hat (32 Bit oder 4 Bytes)." gilt für die Referenzvariable (Macine-Wörter) vom Typ leer (), nicht für die Größe der Klasse selbst (die ein abstrakter Datentyp ist).
quelle
Ich denke, diese Frage ist nur von theoretischem Interesse, spielt aber in der Praxis keine Rolle.
Wie bereits von anderen erwähnt, schadet das Ableiten von einer leeren Klasse nicht, da dadurch kein zusätzlicher Speicher für den Basisklassenabschnitt verbraucht wird.
Wenn eine Klasse leer ist (was bedeutet, dass sie theoretisch keinen Instanzspeicher benötigt, dh keine nicht statischen Datenelemente oder virtuellen Elementfunktionen), können alle ihre Elementfunktionen genauso gut (und sollte) als statisch definiert werden. Es ist also nicht erforderlich, jemals eine Instanz dieser Klasse zu erstellen.
Fazit: Wenn Sie eine leere Klasse X schreiben, machen Sie einfach alle Elementfunktionen statisch. Sie müssen dann keine X-Objekte erstellen, und abgeleitete Klassen sind in keiner Weise betroffen.
quelle
Ausgabe: Okay, es ist in Ordnung, unterschiedliche Adressen zu haben
Durch die Rückgabe von Größe 1 wird sichergestellt, dass die beiden Objekte nicht dieselbe Adresse haben.
quelle
Es ist ungleich Null, um sicherzustellen, dass die beiden unterschiedlichen Objekte unterschiedliche Adressen haben. Unterschiedliche Objekte sollten unterschiedliche Adressen haben, sodass die Größe einer leeren Klasse immer 1 Byte beträgt.
quelle
Ich denke, wenn die Größe einer leeren Klasse Null ist, bedeutet dies, dass sie nicht existiert. Damit es (Klasse) existiert, muss es mindestens 1 Byte haben, da dieses Byte die Speicher- / Referenzadresse ist.
quelle
Dies liegt an diesem Zeiger, obwohl der Zeiger (Ganzzahl) 4 Byte beträgt, sich jedoch auf einen Speicherplatz (eine Einheit) bezieht, der 1 Byte beträgt.
quelle