Поделиться через


Виртуальные базовые классы

Поскольку класс может быть косвенным базовым классом к производному классу более одного раза, C++ позволяет оптимизировать способ рабочий базовых классов.Виртуальные базовые классы предоставляют способ сохранения места и избежать неоднозначности в иерархиях класса, которые используют множественное наследование.

Каждый nonvirtual объект содержит копию указанных элементов данных в базовом классе.Это альтернативный расточительствует пробел и требует указании которой копии члены базового класса требуется при доступе к ним.

Если базовый класс определен как виртуальный базовый класс, он может работать как основа косвенное несколько раз без дублирования его элементов данных.Одна копия его элементов данных совместно используется всеми базовыми классами, которые используют ее как виртуальный базовый класс.

При объявлении виртуального базового класса, Виртуальный ключевое слово появляется в базовые списки производных классов.

Рассмотрим иерархию класса на следующем рисунке, в которой показаны сымитированную линию обеда.

сымитированная диаграмма Обед-Линии

Имитация графа Lunch-Line

В диаграмме Queue базовый класс для обоих CashierQueue и LunchQueue.Однако, если оба класса, должны объединяться для формирования LunchCashierQueueследующая проблема возникает: новый класс содержит 2 subobjects типа Queueодно из CashierQueue а другое из LunchQueue.На следующем рисунке показана conceptual topic структуру памяти (фактическая структура памяти, может быть оптимизирована).

Объект Обед-Линии моделируемый

Имитация объекта Lunch-Line

Обратите внимание, что 2 Queue в subobjects LunchCashierQueue объект.В следующем коде объявляется Queue быть виртуального базового класса:

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

virtual ключевое слово гарантирует, что только одна копия subobject Queue включен (см. следующий рисунок).

Моделируемый объект Обед-Линии с помощью виртуальных базовых классов

Имитация объекта Lunch-Line классами VS

Класс может содержать компонент и фактически и nonvirtual компонента заданного типа.Это происходит в условиях, показанных на следующем рисунке.

Виртуальный Nonvirtual и компоненты одного класса

Виртуальные и не виртуальные компоненты одного класса

В диаграмме CashierQueue и LunchQueue используйте Queue как виртуальный базовый класс.Однако TakeoutQueue определяет Queue как базовый класс, а не виртуального базового класса.Следовательно, LunchTakeoutCashierQueue имеет значение 2 subobjects типа Queue. одно из пути наследования, который включает LunchCashierQueue и одно из пути, который включает TakeoutQueue.Это показано в следующей диаграмме.

Структура объекта с виртуальным наследованием и Nonvirtual

График Virtual_NonvirtualInheritanceObjectLayout

ПримечаниеПримечание

Виртуальное наследование предоставляет значительные преимущества размера при сравнении с nonvirtual наследования.Однако это может привести к дополнительной обработки издержки.

Если производный класс переопределяет виртуальную функцию, которую он наследует из виртуального базового класса, а если конструктор или деструктор вызовами производного базового класса, работающих с помощью указателя на виртуальный базовый класс, компилятор может вставить дополнительные скрытые поля «vtordisp» в классы с виртуальным основаниями.Параметр компилятора /vd0 отключает добавление скрытых членов смещения конструктора или деструктора vtordisp.Параметр компилятора /vd1, значение по умолчанию включает их в которых они требуются.Отключите vtordisps, только если есть уверенность, что все конструкторы и деструкторы классов вызывают виртуальные функции виртуальным.

/vd - Параметр компилятора влияет на весь модуль компиляции.используйте vtordisp директива pragma для подавления а затем reenable поле vtordisp - класс на основе класса:

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

См. также

Ссылки

Несколько базовых классов