您的位置:首页 > 编程语言 > C语言/C++

关于c++中的virtual继承的总结

2014-06-26 19:55 330 查看
1.在什么时候需要虚拟继承呢?

虚拟继承是多重继承特有的概念。虚拟基类是为了解决多重继承而出现的。例如A继承了Y,Z。而Y,Z继承自X,因此A两次出现了类x中的变量和函数,可以将Y,Z定义为虚拟继承。而x则变成了虚拟继承的基类

class X{ };

class Y: public virtual X{ };

class Z: public virtual X{ };

class A :public Y, public Z{ };

上述的X,Y,Z,A中都没有任何一个class中含有明显的数据,只表明了之间的继承关系。所以认为每个的大小都为0?当然不对。即使是class X的大小也不为0;

#include<iostream>

using namespace std;

class A{

};

class B:public virtual A{

};

class C: public virtual A{

};

class D:public B,public C{

};

int main()

{
int a , b , c , d;

a = sizeof(A);
b = sizeof(B);
c = sizeof(C);
d = sizeof(D);

cout<<a << b <<c <<d<<endl;

return 0;

}

本程序在vc6.0运行的结果为:

1448

Press any key to continue

但是为了一个空的类会占用这么多的空间呢?

对于class A来说, 编译器为空类X分配了一个char的空间,所以会占用一个空间的字节。

而对于b,c来说,都保存了一个指向虚拟基类的指针。故占用4个字节,class D同理。

事实上b,c的大小受到了三个因素的影响

1.语言本身所造成的额外负担。

当语言支持virtual base的时,就会导致一些额外的负担,在diriver class中,这个额外的负担就反应在某种形式的指针上面,他指向virtual base class subobject,或者是指向一个相关的表格(virtual table),表格中存放的不是virtual base class subobject的地址 ,就是他的偏移量。

2.编译器对于特殊情况所提供的优化处理

3.alignment的限制

alignment就是数值调整到某数的整数倍,在32位计算机上面,通常alignment为4 byte ,以使bus的“运输量”达到最高效率。

那么虚拟继承与直接继承有什么区别呢?

由于有了间接性和共享性两个特征,所以决定了虚继承体系下的对象在访问的时候必然会在时间和空间下有很大的不同。

1)。时间:在通过继承访问虚基类中的成员的时候,都必须通过某种间接来完成,这样会增加引用寻址空间。其实就是调整this指针指向虚基类对象,只不过这个调整是在运行期完成的。

2)空间:由于共享所以不必要在对象内存中保存多份虚基类子对象的拷贝。这样与多继承相比,节约了空间。继续继承与普通继承不同的是,虚拟继承可以防止diamond继承时,一个派生类出现了两个基类的子对象。也就是说,为了保证这一点,在虚拟继承的情况下,基类子对象的布局是不同于普通继承的。因此,他只需要多出一个指向基类子对象的指针。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++