Ich fand, dass MSVC und GCC-Compiler mindestens ein Byte pro Klasseninstanz zuweisen, selbst wenn die Klasse ein Prädikat ohne Membervariablen (oder nur mit statischen Membervariablen) ist. Der folgende Code veranschaulicht den Punkt.Warum belegen C++ - Klassen ohne Membervariablen Platz?
#include <iostream>
class A
{
public:
bool operator()(int x) const
{
return x>0;
}
};
class B
{
public:
static int v;
static bool check(int x)
{
return x>0;
}
};
int B::v = 0;
void test()
{
A a;
B b;
std::cout << "sizeof(A)=" << sizeof(A) << "\n"
<< "sizeof(a)=" << sizeof(a) << "\n"
<< "sizeof(B)=" << sizeof(B) << "\n"
<< "sizeof(b)=" << sizeof(b) << "\n";
}
int main()
{
test();
return 0;
}
Ausgang:
sizeof(A)=1
sizeof(a)=1
sizeof(B)=1
sizeof(b)=1
Meine Frage ist, warum Compiler braucht es? Der einzige Grund, den ich finden kann, ist sicherzustellen, dass alle Mitglieds-Var-Zeiger unterschiedlich sind, so dass wir zwischen zwei Mitgliedern vom Typ A oder B unterscheiden können, indem wir Zeiger auf sie vergleichen. Aber die Kosten dafür sind ziemlich streng im Umgang mit kleinen Behältern. In Anbetracht der möglichen Datenausrichtung können wir bis zu 16 Bytes pro Klasse ohne vars (?!) Erhalten. Angenommen, wir haben einen benutzerdefinierten Container, der normalerweise einige int-Werte enthält. Betrachten Sie dann ein Array solcher Container (mit etwa 1000000 Mitgliedern). Der Overhead wird 16 * 1000000 sein! Ein typischer Fall, in dem dies passieren kann, ist eine Containerklasse mit einem Vergleichsprädikat, das in einer Membervariablen gespeichert ist. Bedenkt man außerdem, dass eine Klasseninstanz immer etwas Platz einnehmen sollte, welche Art von Overhead sollte man beim Aufruf von A() (value) erwarten?
Nur zur Bestätigung Ihres Verdachts: * Sofern es sich nicht um ein Bitfeld handelt (9.6), muss ein am weitesten abgeleitete Objekt eine Größe ungleich Null haben und ein oder mehrere Speicherbytes belegen. Unterobjekte der Basisklasse dürfen keine Größe haben. * – chris
FYI: Unterobjekte der Größe 0 * sind erlaubt. Wenn Sie also von einer solchen leeren Klasse ableiten und ein weiteres Mitglied der Größe x hinzufügen, ist es wahrscheinlich, dass die Größe Ihres abgeleiteten Typs ebenfalls x ist. Dies wird als "leere Basisklassenoptimierung" bezeichnet. – sellibitze
Ich glaube, dass sich dort mehrere Fragen überschneiden. Es hat keinen Sinn, eine große Anzahl von Klassen ohne Mitglieder in einem Container zu "speichern". Da es keine Daten gibt, gibt es keinen Unterschied zwischen ihnen. Die Tatsache, dass Klassen ohne Member in C++ eine Größe ungleich Null haben, bedeutet jedoch nicht, dass Klassen, die über Member verfügen, unnötigen Overhead haben würden. Das Speicherausrichtungsproblem ist jedoch ein unabhängiges Problem und ist nicht auf C++ beschränkt. – AlefSin