虚基类(Virtual Base Class)

原创 2004年06月26日 21:15:00

这是我翻译的MSDN中的一篇文章,索引为“virtual base classes”。

  因为一个类可以多次作为一个派生类的非直接基类,C++提供了一种优化这种基类工作的方法。虚基类提供了一种方法,可以在使用多重继承的类层次中节省空间和避免不确定性。

  每个非虚的对象包含基类中定义的数据成员的一个副本。这种复制浪费了空间,并且需要你在访问它们时指定使用哪个基类的成员。

  当一个基类指定为虚基类时,可以象一个多次的非直接基类工作而不需要复制数据成员。一个单一的数据成员的副本被所有以虚基类方式使用的基类共享。

  当声明一个虚基类的时候,关键字virtual出现在派生类的基类列表中。

  考虑如下图的类层次,它表示一个模拟的午餐队列。

###############

  在图中,Queue是CashierQueue和LunchQueue的基类;但是,当后两个类组合形成类LunchCashierQueue时,产生了以下问题:新的类包含了Queue类型的两个子对象,一个来自CashierQueue,而另一个来自LunchQueue。下图表示了内存布局的概念图(实际的内存布局可能会经过优化):

###############

  注意到LunchCashierQueue对象中有两个Queue类型的子对象。以下代码声明了Queue作为虚基类:

// deriv_VirtualBaseClasses.cpp class Queue { // Member list }; class CashierQueue : virtual public Queue { // Member list }; class LunchQueue : virtual public Queue { // Member list }; class LunchCashierQueue : public LunchQueue, public CashierQueue { // Member list }; int main() { }

  关键字virtual保证了只有一个Queue子对象被包含(如下图)。

###########

  对于同一个类型,一个类可以既有它的虚子对象,又有非虚的子对象。在如下图表示的条件下,可以产生这种情况。

##########

  如图所示,CashierQueue和LunchQueue使用Queue作为虚基类,但是,TakeoutQueue指定Queue作为非虚的基类。而且LunchTakeoutCashierQueue有Queue类型的两个子对象:一个来自包含LunchCashierQueue的继承路径,一个来自包含TakeoutQueue的继承路径。如下图所示:

#########

  注意:和非虚继承相比,虚继承提供提供可观的空间节约优点。但是,它也引用了额外的处理开销。

  如果一个派生类重定义了继承自虚基类中的一个虚函数,并且如果派生类的构造或者析构函数使用虚基类的指针来调用此函数,那么编译器可能会引入一个隐藏的名为“vtordisp”的域。/vd0编译器选项禁止生成隐藏的vtordisp构造/析构占位符。而默认的/vd1选项,只有在需要的时候生成。只有当你肯定所有的构造和虚构函数虚拟地调用虚函数时才关闭vtordisp。

  /vd选项影响整个编译模式。可以对逐个类使用vtordisp预编译命令来禁止和随后打开vtordisp域。

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

虚基类(virtual base class)

声明虚基类的一般形式为: class 派生类名 : virtual 继承方式 基类名 经过这样的声明后,当基类通过多条派生路径被一个派生类继承时,该派生类只继承该派生类一次,也就是...
  • zhu2695
  • zhu2695
  • 2016年08月23日 11:47
  • 259

virtual base class(虚基类)

对于虚基类(virtual base class),目的是为了解决“多继承中的菱形继承的问题”。 如, class Animal { public: virtual void eat();...
  • klq8505
  • klq8505
  • 2014年04月24日 11:05
  • 324

C++虚基类(virtual base class)

参考http://www.learncpp.com/cpp-tutorial/118-virtual-base-classes/ #include using namespace std; clas...
  • zhanglei0107
  • zhanglei0107
  • 2013年10月02日 12:54
  • 3991

C++虚基类构造函数详解(调用顺序)之一

原文  http://www.cnblogs.com/haoyuanyuan/archive/2013/04/25/3041250.html 主题 C++ 面向对象编程 解释某个函...
  • SunboyJohn690905084
  • SunboyJohn690905084
  • 2016年07月17日 10:50
  • 1418

虚函数表的测试小demo

关于若干种继承下虚函数表的访问         基于64bit os实现,32bit请自动换成int * #include #include #include using namespace ...
  • believe0ne
  • believe0ne
  • 2016年04月29日 21:15
  • 142

c++中包含empty virtual base class 类的sizeof结果分析

前言:最近研读《inside the c++ object model》看到Data语义学一开篇jiu
  • personmy
  • personmy
  • 2014年07月07日 10:39
  • 585

C++ - 纯虚函数(pure virtual) 和 抽象基类(abstract base class)

纯虚函数(pure virtual) 和 抽象基类(abstract base class)   本文地址: http://blog.csdn.net/caroline_wendy   纯虚函数(pu...
  • u012515223
  • u012515223
  • 2013年11月13日 14:54
  • 3893

Delphi提示解决方法

H2365 Override method ***Form.Createparams should match case of ancestor TCustomForm.CreateParams 这是...
  • stbaby
  • stbaby
  • 2013年12月11日 16:07
  • 602

笔试题(一)

1. 以下程序的输出: #include using namespace std; class Base { public: Base(int j) : i(j) {} ...
  • bolike
  • bolike
  • 2014年02月15日 18:28
  • 976

虚基类的初始化

  假设有如下的类:基类B,虚继承派生类D1, D2, 最终派生类F,多继承自D1, D2。 1. B的直接派生类,D1和D2,其初始化列表中要显式地调用B的构造函数;2. B的间接派生类,F,其初始...
  • pc_fly
  • pc_fly
  • 2008年03月13日 13:55
  • 701
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:虚基类(Virtual Base Class)
举报原因:
原因补充:

(最多只允许输入30个字)