Virtuelle Basisklassen

Da eine Klasse eine indirekte Basisklasse mehrfach in einer abgeleiteten Klasse sein kann, stellt C++ eine Methode, die solche Optimierung Methode der Basisklasse.Virtuelle Basisklassen bieten eine Möglichkeit, Platz zu sparen und Mehrdeutigkeiten in den Klassenhierarchien Mehrfachvererbung zu vermeiden.

Jedes nicht virtuell Objekt enthält eine Kopie der Datenmember, die in der Basisklasse definiert sind.Diese Duplikat und verschwendet Leerzeichen anzugeben, müssen Sie dem Kopieren der Basisklassenmember Sie möchten, dass immer dann, wenn Sie auf sie zugreifen.

Wenn eine Basisklasse als virtuelle Basisklasse angegeben ist, kann sie als eine indirekte Basisklasse ohne Duplikat seiner Datenmember mehrmals vorkommen.Eine einzelne Kopie der Datenmember wird von allen Basisklassen gemeinsam genutzt, die diese als virtuelle Basisklasse verwenden.

Wenn es sich um eine virtuelle Basisklasse deklariert, wird das virtuell-Schlüsselwort in den Listen der Basisklasse abgeleiteten Klassen.

Betrachten Sie die Klassenhierarchie in der folgenden Abbildung Mittagessen, die eine simulierte Zeile veranschaulicht.

Simuliertes Mittagessen-Zeile Diagramm

Diagramm der Lunchsimulation

In der Abbildung ist Queue die Basisklasse für CashierQueue und LunchQueue.Wenn jedoch beide Klassen kombiniert werden, um LunchCashierQueuezu erstellen, tritt auf das nächste Problem: die neue Klasse enthält zwei Unterobjekte Queuedes Typs, der von CashierQueue und die andere von LunchQueue.In der folgenden Abbildung sind das konzeptionelle Arbeitsspeicher Lay-out an (die tatsächlichen Speicherplatz Lay-out möglicherweise würde optimiert).

Simuliertes Mittagessen-Zeile Objekt

Objekt der Lunchsimulation

Beachten Sie, dass es zwei Queue Unterobjekte im LunchCashierQueue-Objekt vorhanden ist.Der folgende Code deklariert Queue , um eine virtuelle Basisklasse sein:

// deriv_VirtualBaseClasses.cpp
// compile with: /LD
class Queue {};
class CashierQueue : virtual public Queue {};
class LunchQueue : virtual public Queue {};
class LunchCashierQueue : public LunchQueue, public CashierQueue {};

Das virtual-Schlüsselwort wird sichergestellt, dass nur eine Kopie des Unterobjekts Queue enthalten ist (siehe folgende Abbildung).

Simuliertes Mittagessen-Zeile Objekt mit virtuellen Basisklassen

VS-Klassen im Objekt der Lunchsimulation

Eine Klasse kann eine virtuelle Komponente und eine nicht virtuelle Komponente eines bestimmten Typs verfügen.Dies geschieht in den Bedingungen, die in der folgenden Abbildung veranschaulicht werden.

Virtuelle und nicht virtuell Komponenten derselben Klasse

Virtuelle und nicht virtuelle Komponenten derselben Klasse

In der Abbildung CashierQueue und LunchQueueQueue als virtuelle Basisklasse.Es gibt TakeoutQueueQueue als Basisklasse keine virtuelle Basisklasse an.Daher verfügt über zwei LunchTakeoutCashierQueue Unterobjekte des Typs Queue: Vererbung ein vom Pfad, der LunchCashierQueue einschließt, und eine der Pfad, der TakeoutQueueeinschließt.Dies wird in der folgenden Abbildung dargestellt.

Objekt-Lay-out mit virtuellen und nicht virtuelle Vererbung

Virtual_NonvirtualInheritanceObjectLayout-Grafik

HinweisHinweis

Virtuelle Vererbung stellt bedeutende Vorteile Größe im Vergleich zu nicht virtuelle Vererbung bereit.Es kann jedoch verursachen, die die zusätzliche Mehraufwand verarbeiten.

Wenn eine abgeleitete Klasse eine virtuelle Funktion überschreibt sie von einer virtuellen Basisklasse erbt, und wenn ein Konstruktor oder einen Destruktor für die Aufrufe der abgeleiteten Klasse, die funktionieren mithilfe eines Zeigers der virtuellen Basisklasse vorstellt der Compiler möglicherweise zusätzliche Hidden „vtordisp“ Felder in Klassen mit virtuellen Basen.Die /vd0- unterdrückt das Hinzufügen des Destruktor-Verschiebungs ausgeblendeter vtordisp-Member/members.Die /vd1-, Standard, ermöglicht es, wo es notwendig sind.Stellen Sie vtordisps ab nur, wenn Sie sicher sind, dass alle Klassenkonstruktoren und Destruktoren virtuelle Funktionen virtuell aufrufen.

Die /vd- wirkt sich das gesamte Modul Kompilierung.Verwenden Sie das vtordisp Pragma, um vtordisp-Felder zu einer Klasse-durch Klasse Basis zu unterdrücken und dann erneut aktivieren:

#pragma vtordisp( off )
class GetReal : virtual public { ... };
#pragma vtordisp( on )

Siehe auch

Referenz

Mehrere Basisklassen