2012-10-31 7 views
9

Im folgenden Code sind aus dem Buch "Im Inneren des Objektmodells C++"Fragen zu C++ virtuelle Vererbung

#include <iostream> 
using namespace std; 
class X{}; 
class Y: public virtual X{}; 
class Z: public virtual X{}; 
class A: public Y, public Z{}; 

int main() 
{ 
    cout<<sizeof(X)<<" "<<sizeof(Y)<<" "<<sizeof(Z)<<" "<<sizeof(A)<<endl; 
    return 0; 
} 

In meinem Computer (Windows, VS2010), der Ausgang ist:

Here're meine Fragen

1, sizeof (X) = 1

Das Buch sagen s Wenn X-Typ zwei Instanzen generiert, sagen wir xa und xb. Die Kompilierung fügt ein Byte in A ein, so dass xa und xb unterschiedliche Adressen haben können. Ich verstehe die Gründe nicht ganz.

2, sizeof (Y) = 4

Durch virtuelle Vererbung, werden wir einen zusätzlichen virtuellen Zeiger? Ich denke, das könnte sich vom Polymorphismus unterscheiden. Kann mir jemand das Speicherlayout für Y geben?

Vielen Dank!

+0

Eine Frage pro Frage bitte –

+0

für die 1. Frage, zu überprüfen: http://StackOverflow.com/Questions/621616/c-what-is-the-size-of-an- object-of-empty-class? rq = 1 –

+1

Ich denke, Ihre Hauptfrage ist, dass, weil Y die virtuelle Vererbung verwendet, um von einer nicht-polymorphen Klasse X abzuleiten, und Y selbst nicht-polymorph ist, wird die virutale Vererbung selbst verursachen Y, um eine v-Tabelle so seine Größe zu haben 4 .. – CashCow

Antwort

6
  1. Compiler neu ein Zeichen, wenn die Klasse leer ist, so kann es verschiedenes Objekt
  2. sizeof (Y) = 4 erzeugen, weil es virtuell ist Vererbung, Konstrukt wird vptr Tabelle generieren, die 4 Bytes auf 32-Bit-System ist
  3. Wenn Sie Visual Studio verwenden verwenden/d1reportAllClassLayout in Eigenschaften-> C/C++/Command zum Erstellen von Objektlayout Klasse Y Objektlayout wird auf Visual sein Studio:
  4. Buch 'Inside C++ Objektmodell' von Stanley B. Lippman erklärte dies extrem gut


     class Y size(4): 
      +--- 
      0  | {vbptr} 
      +--- 
      +--- (virtual base X) 
      +---
Y::[email protected]: 0 | 0 1 | 4 (Yd(Y+0)X)

vbi: class offset o.vbptr o.vbte fVtorDisp X 4 0 4 0
1

sizeof einer leeren Klasse gibt immer 1 zurück. Das ist ein einzelnes Dummy-Byte für eine leere Klasse.

A hält die beiden Einträge in der virtuellen Tabelle, eine für Y andere für Z

So sind die beiden Zeiger sizeof dh 8.

Y und Z halten beide einen einzigen Eintrag von X haben in ihre virtuelle Tabelle, daher ist die Größe 4.

+0

Ich sehe keine Klassen namens B und C hier – CashCow

1

ein ein Objekt wird ein Y-Objekt, ein Z-Objekt enthält (in dieser Reihenfolge), und nur ein X-Objekt (durch Zeiger in Y und Z referenziert), weil Sowohl Y als auch Z erben virtuell von X, was bedeutet, dass, wenn Mehrfachvererbung zum Einsatz kommt, nur ein X-Objekt in den Kindklassen instanziiert wird. A hat immer noch zwei Objekte (ein Y, ein Z) und hat daher eine Größe von = 8 (da beide Größe = 4 haben). Aber beide Zeiger in Y und Z auf das X-Objekt zeigen auf die gleiche Adresse.

wird die Vererbungsbaum wie folgt aussehen:

X 
/\ 
Y Z 
\/
    A 
0

Der Grund Klassen mindestens 1 Byte sein -must- wir eine Reihe von X. sagenWenn sie 0 Bytes wären, hätte & Array [1] die gleiche Adresse wie & Array [3] was niemand erwarten würde, würde Code brechen, nervig sein, wenn Sie Code schreiben mussten, um dafür zu überprüfen und normalerweise nicht machen irgendein Sinn.

Y würde einfach sein

static void* virtual_ptr1 //note this is in virtual table and cannot be edited 

Sie von vtables (virtuellen Zeiger auf Klassen und virtuelle Funktionen) denken können als statische Variablen, die Sie nicht von Hand/Code (oder zumindest nicht sollte) bearbeiten können. Betrachten Sie es als Compiler reserviert statische Variablen

+1

Ich mag diese Erklärung für den Grund sizeof (X) = 1 – Junjie