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

C++菱形继承

2017-06-01 15:27 225 查看
在c++继承体系中,有一类问题是永远跑不掉的即菱形继承问题。此类问题又被称作钻石继承问题,只是一种较差的设计结构,刚好看到这个问题,特此总结一下。

何为菱形继承

先来看一下菱形继承的基本结构



A和B从基类Base中继承,而D多重继承于A,B。那就意味着D中会有Base中的两个拷贝。因为成员函数不体现在类的内存大小上,所以实际上可以看到的情况是D的内存分布中含有2组Base的成员变量。

又因其结构与钻石有几分相似,又被称作钻石继承。



代码如下

class Base
{
public:
Base():a(1){};
void print(){
cout<<a<<endl;
}

private:
int a;
};

class A : public Base
{
};

class B : public Base
{
};

class D:  public A ,  public B
{
};

int main(int argc, char* argv[])
{
D d;
cout<<sizeof(d);
d.a=10;//error : 对“a”的访问不明确
d.print();//error : 对“print”的访问不明确
}


输出d的大小为8。若此时示例化D并调用Base中的print成员函数就会出现二义性问题。

虚继承

如何解决钻石继承问题中的二义性问题呢?通过使用虚继承的手段可以保证D只存有基类Base的一份拷贝,虚继承是一种机制,类通过虚继承指出它希望共享虚基类的状态。对给定的虚基类,无论该类在派生层次中作为虚基类出现多少次,只继承一个共享的基类子对象,共享基类子对象称为虚基类。

其省略后的代码如下所示:

class Base {……};
class A : virtual public Base{……};
class B: virtual public Base{……};
class D : public A, public B{ …… };


虚继承和直接继承会有什么区别

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

空间:由于共享所以不必要在对象内存中保存多份虚基类子对象的拷贝,这样较之多继承节省空间。

最后关于虚继承对象的内存布局 http://blog.csdn.net/BlueDog/article/details/4711169 这篇博文讲的很不错可以作为参考。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++