C++虚继承对内存空间影响分析

1、  虚继承概念

虚继承 (也称为共享继承)是面向对象编程中的一种技术,是指一个指定的基类,在继承体系结构中,将其成员数据实例共享给也从这个基类型直接或间接派生的其它类。

虚继承是多重继承中特有的概念。虚基类是为解决多重继承而出现的。

2、  虚继承和虚基类

虚继承:在继承定义中包含了virtual关键字的继承关系;

虚基类:在虚继承体系中的通过virtual继承而来的基类

举例说明:

class CSubClass: public virtual CBase {};

其中CBase称之为CSubClass的虚基类,而不是说CBase就是个虚基类,因为CBase还可以作为不是虚继承体系中的基类。

3、  为什么使用虚继承

虚继承在一般的应用中很少用到,所以也往往被忽视,这也主要是因为在C++中,多重继承是不推荐的,也并不常用,而一旦离开了多重继承,虚拟继承就完全失去了存在的必要(因为这样只会降低效率和占用更多的空间,关于这一点,我自己还没有太多深刻的理解,有兴趣的可以看网络上白杨的作品《RTTI、虚函数和虚基类的开销分析及使用指导》)。

虚继承是解决C++多重继承(比如菱形继承)问题的一种手段,从不同途径继承来的同一基类,会在子类中存在多份拷贝。这将存在两个问题:其一,浪费存储空间;第二,存在二义性问题,通常可以将派生类对象的地址赋值给基类对象,实现的具体方式是,将基类指针指向继承类(继承类有基类的拷贝)中的基类对象的地址,但是多重继承可能存在一个基类的多份拷贝,这就出现了二义性。

可参阅连接:http://blog.csdn.net/monamokia/article/details/51537312

4、  虚继承实现

虚继承底层实现原理与编译器相关,一般通过虚基类指针虚基类表实现,每个虚继承的子类都有一个虚基类指针(占用一个指针的存储空间,4字节)和虚基类表(不占用类对象的存储空间)(需要强调的是,虚基类依旧会在子类里面存在拷贝,只是仅仅最多存在一份而已,并不是不在子类里面了);当虚继承的子类被当做父类继承时,虚基类指针也会被继承。

 

实际上,vbptr指的是虚基类表指针(virtualbase table pointer),该指针指向了一个虚基类表(virtual table),虚表中记录了虚基类与本类的偏移地址;通过偏移地址,这样就找到了虚基类成员,而虚继承也不用像普通多继承那样维持着公共基类(虚基类)的两份同样的拷贝,节省了存储空间。

在这里我们可以对比虚函数的实现原理:他们有相似之处,都利用了虚指针(均占用类的存储空间)和虚表(均不占用类的存储空间)。

虚基类依旧存在继承类中,只占用存储空间;虚函数不占用存储空间。

虚基类表存储的是虚基类相对直接继承类的偏移;而虚函数表存储的是虚函数地址。

5、  源代码示例

5.1、简单虚继承

///******模式1-只有虚继承

//解析:这里需要理解虚继承基类对派生类的空间大小的影响,理解虚指针在虚继承中为子类带来了哪些空间的改变。

classA

{

public:

    inta;

    virtualfunc();//如果虚基类中存在虚函数,则虚继承的子类中出现虚函数也不再增加存储空间。也可以理解为:虚继承关系的所有类中只有一个选函数指针。

};//sizeof(A)=8

 

classB:  virtualpublicA

{

public:

    intb;

};//sizeof(B)=8(A副本或A的拷贝)+4(虚基类指针)+4(自己变量)=16

 

classC:virtualpublicB

{

    charc;

};//sizeof(c)=16(B副本或B的拷贝)+4(虚基类指针)+4(自己变量)=24

//******/

5.2、多重继承

///******模式2-虚继承+多重继承

//解析:这里需要关注classD的数据空间大小,理解多重虚继承对派生类虚指针以及派生类空间的影响。

classA

{

public:

    inta;

    virtualfunc();

};//sizeof(A)=8

 

classB:virtualpublicA

{

    intb;

};//sizeof(B)=8(A副本或A的拷贝)+4(虚基类指针)+4(自己变量)=16

 

classC:virtualpublicA

{

    intc;

};//sizeof(C)=8(A副本或A的拷贝)+4(虚基类指针)+4(自己变量)=16

 

classD:publicB,publicC

{

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值