Compartilhar via


Classes Base virtuais

Como uma classe pode ser uma classe de base indireta para uma classe derivada de mais de uma vez, o C++ fornece uma maneira de otimizar a maneira como base o trabalho de classes.Classes base virtuais oferecem uma maneira de economizar espaço e evitar ambigüidades nas hierarquias de classe que usam a herança múltipla.

Cada objeto nonvirtual contém uma cópia dos membros de dados definidos na classe base.Essa duplicação desperdiça espaço e exige que você especifique qual cópia dos membros da classe base que você deseja que sempre que você acessá-los.

Quando uma classe base é especificada como uma base virtual, ele pode atuar como uma base indireta mais de uma vez sem duplicação de seus membros de dados.Uma única cópia de seus membros de dados é compartilhada por todas as classes base que usá-lo como uma base virtual.

Ao declarar uma classe base virtual, o virtual palavra-chave aparece nas listas de base das classes derivadas.

Considere a hierarquia de classes na figura a seguir, que ilustra uma linha de almoço simulado.

Gráfico de Lunch-Line simulado

Gráfico de Lunch-Line simulado

Na figura, Queue é a classe base para ambos CashierQueue e LunchQueue.No entanto, quando ambas as classes são combinadas para o formulário LunchCashierQueue, o seguinte problema surge: a nova classe contém dois subobjetos do tipo Queue, um de CashierQueue e outra de LunchQueue.A figura a seguir mostra o layout de memória conceitual (o layout de memória real pode ser otimizado).

Objeto Lunch-Line simulado

Objeto Lunch-Line simulado

Observe que há dois Queue subobjects na LunchCashierQueue objeto.O seguinte código declara Queue seja uma classe base virtual:

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

O virtual palavra-chave garante que somente uma cópia do subobjeto Queue está incluído (consulte a figura a seguir).

Objeto de linha de almoço simulado com Classes Base virtuais

Objeto Lunch-Line simulado de Classes VS

Uma classe pode ter um componente virtual e um componente de nonvirtual de um determinado tipo.Isso acontece nas condições ilustradas na figura a seguir.

Componentes virtuais e Nonvirtual da mesma classe

Virtual & Componentes de classe mesmo não virtuais

Na figura, CashierQueue e LunchQueue usar Queue como uma classe base virtual.No entanto, TakeoutQueue especifica Queue como uma classe base, não uma classe base virtual.Portanto, LunchTakeoutCashierQueue tem dois subobjetos do tipo Queue: o caminho de herança que inclui uma LunchCashierQueue e outro do caminho que inclui TakeoutQueue.Isso é ilustrado na figura a seguir.

Layout de objetos com herança Virtual e Nonvirtual

De Virtual_NonvirtualInheritanceObjectLayout

ObservaçãoObservação

Herança virtual fornece benefícios de tamanho significativo quando comparado com a herança de nonvirtual.No entanto, ele pode introduzir a sobrecarga de processamento extra.

Se uma classe derivada substituir uma função virtual que ele herda de uma classe base virtual e um construtor ou um destruidor para as chamadas de classe base derivada que funcionam usando um ponteiro para a classe base virtual, o compilador pode apresentar campos adicionais ocultos "vtordisp" nas classes com bases virtuais.A opção de compilador /vd0 suprime a adição do membro vtordisp oculto constructor/destructor deslocamento.A opção de compilador /vd1, o padrão, permite que eles onde eles são necessários.Desative vtordisps somente se tiver certeza de que todos os construtores de classe e destruidores chamam funções virtuais virtualmente.

A opção de compilador /vd afeta um módulo de compilação inteira.Use o vtordisp pragma para suprimir e depois reabilitar os campos de vtordisp em uma base de classe a classe:

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

Consulte também

Referência

Várias Classes Base