2010-03-02 4 views
55

Mögliche Duplizieren:
C++: What is the size of an object of an empty class?Warum ist die Größe einer leeren Klasse in C++ nicht Null?

Warum wird die folgende Ausgabe 1?

#include <iostream> 

class Test 
{ 
}; 

int main() 
{ 
    std::cout << sizeof(Test); 
    return 0; 
} 
+4

Es gibt ein Dummy-Platzhalterelement, dessen Größe ein Byte beträgt. Da für ein Array von Test [10] jedes Objekt eine eindeutige Adresse haben sollte. – legends2k

+4

Eine interessante Optimierung ist jedoch die 'Empty Base Optimization', das heißt, wenn Sie von einer leeren Basisklasse erben (kein Attribut, keine virtuellen Methoden), dann wird Ihre Klassengröße nicht wachsen. Es gibt eine Reihe von (anderen) Bedingungen, aber es erklärt, warum in einigen Situationen privat Prädikate erben. –

+0

[ähnliche Frage 1] (http://stackoverflow.com/questions/1626446) und [ähnliche Frage 2] (http://stackoverflow.com/questions/621616/). – Lazer

Antwort

86

Der Standard erlaubt keine Objekte (und Klassen davon) der Größe 0, da, dass es möglich machen würde, für zwei verschiedene Objekte die gleiche Speicheradresse haben. Deshalb müssen auch leere Klassen eine Größe von (mindestens) 1 haben.

+2

Hm ... aber sollte nicht der Linker dafür sorgen können, unabhängig davon, welche Größe von() zurückgegeben wird? Ist das nicht eher ein Nebeneffekt? Ich verstehe, was Sie sagen, aber ist es nicht vollkommen möglich, 0 für sizeof (Test) zurückzugeben. Aber wenn der Standard dies sagt, sagt es das auch. Eigentlich eine gute Sache, einmal explizit statt absichtlich vage über ein Thema zu sein. –

+12

@Amigable, also was hätte 'Test a [10];' als Größe? Und "sizeof a/sizeof * a" würde durch 0 dividieren. Und "für (Test * i = a; i! = A + 10; i ++) f (i);" würde auch nicht funktionieren. Ich glaube, es würde viele Probleme verursachen, da Sie in Compilern * und * im Benutzercode viele Spezialfälle benötigen. –

+0

@Johannes, so wahr. Daran habe ich nicht gedacht. –

27

Um sicherzustellen, dass die Adressen von zwei verschiedenen Objekten unterschiedlich sind. Aus dem gleichen Grund gibt "new" immer Zeiger auf unterschiedliche Objekte zurück.

Vollständige Antwort siehe Stroustrup.

+1

Zum direkten Seitenlink gehen –

20

Der C++ - Standard garantiert, dass die Größe jeder Klasse mindestens eins ist. Der C++ - Standard besagt, dass kein Objekt die gleiche Speicheradresse wie ein anderes Objekt haben soll. Dafür gibt es mehrere gute Gründe.

  1. Um zu gewährleisten, dass new immer einen Zeiger auf eine eindeutige Speicheradresse zurück.

  2. Um einige Divisionen durch Null zu vermeiden. Zum Beispiel beinhalten Zeigerarithmetik (von denen viele automatisch vom Compiler ausgeführt werden) das Teilen durch sizeof(T).

ist jedoch zu beachten, dass es nicht bedeutet, dass eine leere Basisklasse 1 auf die Größe einer abgeleiteten Klasse hinzufügen wird:

struct Empty { }; 

struct Optimized : public Empty { 
    char c; 
}; 

// sizeof(Optimized) == 1 with g++ 4.0.1 

Bjarne Stroustrup talks about this auch.

+2

Welche Zeigerarithmetik beinhaltet _dividieren_ durch 'sizeof (T)'? Ich kann mir kein einziges Beispiel vorstellen. Bitte fügen Sie mindestens ein Beispiel hinzu. – MSalters

+4

@MSalters: Iterieren über Arrays von Elementen des Typs T. – wilhelmtell

+1

@MSalters: Subtraktion von zwei Zeigern gibt die Anzahl der Elemente, nicht die Anzahl der Bytes dazwischen. –

3

Was Maurits und Péter gesagt haben.

Es ist interessant, in diesem Zusammenhang, dass Compiler leere Basisklasse Optimierung tun kann (EBCO):

#include <iostream> 
struct Foo {}; 
struct Bar : Foo {}; 
int main() { 
    std::cout << sizeof(Foo) << ',' << sizeof(Bar) << std::endl;   
} 

Dies ist wahrscheinlich „1,1“ gedruckt wird, wenn Sie kompilieren und ausführen. Siehe auch Vandevoorde/Josuttis 16.2 auf EBCO.

9

Klasse ohne Daten Member und Member-Funktion dieser Art der Klasse wird als leere Klasse bezeichnet. Die Größe des Objekts der leeren Klasse ist immer 1 Byte.

Wenn wir Objekt einer Klasse zu dieser Zeit erstellen, erhält Objekt immer 3 Eigenschaften, d.h.nichts ist

  1. Staat
  2. Verhalten
  3. Identität

Wenn wir Objekt der leeren Klasse zu diesem Zeitpunkt Staat dieses Objekts erstellen. Das Verhalten dieses Objekts ist ebenfalls nichts, aber der Compiler weist diesem Objekt eine eindeutige Adresse zu. Der Speicher im Computer ist immer in Form von Bytes organisiert, und der minimale verfügbare Speicher an der Adresse der Objektadresse ist 1 Byte. Aus diesem Grund beträgt die Größe des Objekts der leeren Klasse 1 Byte.

+0

wenn jemand etwas über Eigenschaften eines Objekts wissen möchte, d. H. 1) Zustand 2) Verhalten 3) Identität dann frage mich – Shantanu

Verwandte Themen