2009-07-20 26 views
2

Kompilieren Sie die folgende KlasseWas ist eine "fast-leere" Klasse?

class Interface 
{ 
    virtual void doIt() = 0; 
    virtual ~Interface() = 0; 
}; 

inline Interface::~Interface() {} 

gcc -fdump-class-hierarchy verwenden.

gcc emittiert

 
Class Interface 
    size=4 align=4 
    base size=4 base align=4 
Interface (0x1a779c0) 0 nearly-empty 
    vptr=((& Interface::_ZTV9Interface) + 8u) 

Was ist die Bedeutung von "fast leer"? Was heißt das?

+0

Nicht verwandt aber .. Machen Sie virtuellen Destruktor nicht als rein virtuell, wie Sie die Implementierung bereitstellen. – Naveen

+4

Ich denke nicht, dass das ein besonders guter Rat ist. Reine virtuelle Destruktoren sind eine gebräuchliche Kurzform, um zu sagen, dass die Klasse abstrakt ist und dass sie eine Implementierung haben müssen. –

+1

@ Naveen: Warum nicht? Jede reine virtuelle Funktion kann eine Implementierung haben. – dalle

Antwort

4

Die C++ ABI eine Definition von „fast leer“ Klassen und eine interessante Diskussion darüber, wie sie VTable Konstruktion beeinflussen:

Eine Klasse, die einen virtuellen Zeiger enthält, aber keine anderen Daten außer (möglicherweise) virtuelle Basen . Insbesondere ist es:

  • hat keine nicht-statische Datenelemente ungleich Null-Breite bitfields,
  • hat keine direkten Basisklassen, die nicht entweder leer, fast leer sind, oder virtuell,
  • hat bei die meisten eine nicht virtuelle, fast leere direkte Basisklasse, und
  • hat keine richtige Basisklasse, die leer ist, nicht moralisch virtuell und mit einem anderen Offset als Null.

ich auf diesem während lief die Wirkung von fast leeren virtuellen Basen auf Objektgröße, VTable Größe und virtuelle Call-Overhead zu erforschen.

3

Es hat nur eine VTable, keine Datenfelder.

6

Ich nehme an, es ist von "leer" zu unterscheiden, was Sie erhalten, wenn Sie eine Klasse ohne Mitglieder kompilieren. "fast leer" scheint zu bedeuten, dass es eine Tabelle und nichts anderes hat.

6

C++ hat eine so genannte "leere Basis-Optimierung". Wenn eine Klasse keine Mitglieder hat, braucht sie nicht Platz zu beanspruchen, wenn sie als Basisklasse verwendet wird. Ein Beispiel dafür, warum dies wichtig ist, ist std::unary_function<T, U>. Es existiert, um Ihnen eine einfache Reihe von typedefs zur Verfügung zu stellen. Diese typedefs sollte nicht zur Größe Ihrer Funktorklasse beitragen.

Wenn Sie eine Basisklasse mit einem vtable-Zeiger haben, kann dieser Zeiger wahrscheinlich mit der abgeleiteten Klasse geteilt werden. Sie erstellen einfach eine V-Tabelle für die abgeleitete Klasse, die ihre eigenen Methoden nach der Basisklasse hinzufügt.

Sie können jetzt eine ähnliche "no extra overhead" Basisklasse erreichen. Anscheinend nennt GCC das "fast leer".

+0

Klingt plausibel. Haben Sie einen Hinweis, um es zu bestätigen? – Tobias