Grundsätzlich ist es eine Nachverfolgung von diese Frage ..
Wenn ich mir die Standarddokumente ansehe, habe ich das gefunden.
In Klassen 9.3 ,
Komplette Objekte und Member-Unterobjekte des Klassentyps müssen eine Größe ungleich Null haben. 96) ...
Ja, stimmt .. Aber,
96) Unterobjekte der Basisklasse sind nicht so eingeschränkt .
Also, als ich in Stroustrups FAQ nachgeschaut habe, gibt es ein Beispiel dafür
%Vor%Meine Frage ist, ich konnte nicht verstehen, wie es eine Optimierung ist und auch warum Basisklassen keine Größe haben dürfen ?
Basisklassen können nicht eine Größe von null haben. Nur Basisklassen Unterobjekte können. Bedeutung des Basisteils des abgeleiteten Objekts.
Wenn die Basisklasse leer ist, brauchen Sie weder die Adresse des Basisklassenobjekts noch eine der Adressen seiner Mitglieder (unabhängig von der Adresse der abgeleiteten Klassenobjekte), daher ist es legal, die Größe zu optimieren.
Das spart Ihnen (mindestens) ein Byte Speicher (kann mehr durch Speicherausrichtungsregeln entstehen), was zu erheblichen Einsparungen führen kann, wenn Sie Millionen solcher Objekte in Ihrer App auf einer speicherbeschränkten Plattform haben.
Ich bin kein Raymond Chen, aber ich kann das Spiel "Was wäre, wenn es wahr wäre" spielen.
Wenn eine Klasse, die als Referenz übergeben werden kann, eine Größe von null haben kann, kann sie zu einem bestimmten Zeitpunkt an malloc(0)
übergeben werden, was NULL oder eine dereferenzierbare Adresse zurückgeben kann. Dann könnten zwei Instanzen gleich erscheinen, wenn sie nicht sollten.
Wenn es jedoch ein Member einer anderen Klasse oder einer Basisklasse ist, werden seine Adresse und seine Größe von seiner Position in der enthaltenden Klassenzuordnung abgeleitet, und es ist sicher, dass es null ist.
Und die Größe 0 ist gut für die Speichereffizienz.
Die Größe eines Objekts ist nichts anderes als die kumulative Größe seiner Elemente. Und NEIN, keine Klasse kann eine Nullgröße haben, selbst eine leere Klasse wird eine Größe von 1 Byte haben.
Was hier mit
gemeint ist Base class subobjects are not so constrained.
ist, dass das Objekt selbst keinen Platz verbraucht, sondern eher Mitglieder. So kann die Adresse eines Objekts mit der seines ersten Teilobjekts übereinstimmen, wie im Fall von arrays
. Das ist die Optimierung.
Im Falle einer abgeleiteten Klasse enthält sie notwendigerweise das Basisklassenobjekt, das sogar leer 1 Byte verbraucht, daher ist obige Optimierung für eine abgeleitete Klasse nicht gültig.
Dies ist eine Optimierung, da Instanzen der abgeleiteten Klasse weniger Speicherplatz benötigen als sie hätten, wenn die Unterobjekte der Basisklasse eine Größe ungleich Null hätten. Dies bedeutet, dass Basisklassen wie Schnittstellen oder Mix-Ins oder Vorlagenrichtlinienklassen die Größe von Klassen, die sie implementieren oder verwenden, nicht erhöhen. Letztendlich benötigt Ihr Programm weniger Speicher, um dasselbe zu tun.
Ich bin nicht ganz sicher in der Geschichte, aber der Eindruck, den ich bekomme, ist, dass irgendwann in den neunziger Jahren einige Compiler damit angefangen haben und das Standardkomitee beschlossen hat, die bestehende Praxis zu standardisieren. Ich denke, die Verbreitung von Allokator-Objekten in STL-Vorlagen war Teil des Grundes - ein std::vector
wäre normalerweise die Größe von 3 Zeigern mit der leeren Basisoptimierung und 4 Zeigern ohne es (aufgrund der Ausrichtung). Hier ist ein Artikel aus dem Jahr 1997, der darüber diskutiert - es ist klar, dass es nicht so weit verbreitet war, als das geschrieben wurde, aber es ist im Grunde Standardpraxis jetzt.
Tags und Links c++