Diese Frage bezieht sich nicht auf die C++ - Sprache selbst (dh nicht auf den Standard), sondern darauf, wie ein Compiler aufgerufen wird, um alternative Schemata für virtuelle Funktionen zu implementieren.Alternative Schemata zur Implementierung von vptr?
Das allgemeine Schema zum Implementieren virtueller Funktionen verwendet einen Zeiger auf eine Tabelle von Zeigern.
class Base {
private:
int m;
public:
virtual metha();
};
äquivalent in sagen würde C so etwas wie
struct Base {
void (**vtable)();
int m;
}
das erste Element in der Regel ein Zeiger auf eine Liste der virtuellen Funktionen usw. (ein Stück Bereich im Speicher, die die Anwendung hat keine Kontrolle über). Und in den meisten Fällen kostet dies die Größe eines Zeigers, bevor man die Member usw. berücksichtigt. Also in einem 32-Bit-Adressierungsschema um 4 Bytes usw. Wenn Sie eine Liste von 40.000 polymorphen Objekten in Ihren Anwendungen erstellt haben, sind dies etwa 40.000 4 Bytes = 160k Bytes vor irgendwelchen Mitgliedsvariablen usw. Ich weiß auch, dass dies die schnellste und gebräuchlichste Implementierung unter C++ - Kompilierungen ist.
Ich weiß, dass dies durch Mehrfachvererbung (besonders mit virtuellen Klassen in ihnen, dh Diamant-Struktur, usw.) kompliziert ist.
Eine alternative Möglichkeit, das gleiche zu tun, ist die erste Variable als Index-ID auf eine Tabelle von vptrs (äquivalent in C wie unten)
struct Base {
char classid; // the classid here is an index into an array of vtables
int m;
}
die Gesamtzahl der Klassen in einer Anwendung, die bis haben, ist weniger als 255 (einschließlich aller möglichen Template-Instanziierungen, usw.), dann ist ein char gut genug, um einen Index zu halten, wodurch die Größe aller polymorphen Klassen in der Anwendung reduziert wird (Ich schließe Ausrichtungsprobleme usw. aus).
Meine Fragen ist, gibt es irgendeinen Schalter in GNU C++, LLVM oder irgendeinem anderen Compiler, um dies zu tun ?? oder reduzieren Sie die Größe von polymorphen Objekten?
Bearbeiten: Ich verstehe über die Ausrichtung Probleme hingewiesen. Auch ein weiterer Punkt, wenn dies in einem 64-Bit-System (unter der Annahme von 64 Bit vptr) mit jedem polymorphen Objektelement, das ungefähr 8 Byte kostet, ist, dann betragen die Kosten von vptr 50% des Speichers. Dies bezieht sich hauptsächlich auf kleine Polymorphe, die in Masse erzeugt werden, also frage ich mich, ob dieses Schema für zumindest bestimmte virtuelle Objekte möglich ist, wenn nicht die gesamte Anwendung.
Das Element m würde wahrscheinlich immer noch auf einer DWORD-Grenze ausgerichtet sein, so dass Sie nichts gewinnen würden. – Henrik
Das Problem mit diesem Schema würde wahrscheinlich eine der Ausrichtung sein. Hier würde die Strukturbasis in Ihrem zweiten Beispiel nicht (im Allgemeinen) 5 Bytes einnehmen, wodurch Sie 3 Bytes pro Objekt sparen würden. Das m würde wahrscheinlich sowieso auf einer 4-Byte-Grenze ausgerichtet sein, so dass Sie 3 Bytes verschwendeten Speicherplatzes hätten. –
Ich denke, dass diese Methode der virtuellen Tabellenimplementierung fast universell ist. Ich habe sicherlich noch nie eine andere Methode oder irgendwelche Optionen für GCC oder Visual C++ gefunden, die die Implementierung steuern würden. –