菱形继承问题和虚继承是如何解决二义性与数据冗余的
2017-07-21 21:30
393 查看
菱形继承问题和虚继承是如何解决二义性与数据冗余的
继承是c++的三大特性之一,其中菱形继承问题是一个值得我们学习和掌握的知识点。1.什么是菱形继承呢?
菱形继承定义为:两个子类继承同一个父类,而又有子类同时继承这两个父类。
可能这样纯粹的文字大家不能直观的理解它,下面画一幅直观图便可一目了然:
菱形继承的代码描述如下:
#include<iostream> using namespace std; class A { public: int _a; }; class B : public A { public: int _b; }; class C : public A { public: int _c; }; class D :public B, public C { public: int _d; }; void Test() { D d; d.B::_a = 1; d.C::_a = 2; } int main() { Test(); return 0; }
可以看到,在对_a赋值时,必须使用域访问限定符,否则无法识别是对BB对象还是对CC对象中的 _a赋值,虽然这样解决了二义性问题,但是又产生了数据冗余的问题.
2.如果要解决二义性和数据冗余的问题,则又需要引入虚继承的概念。
虚继承是在class B : public A与class C :public A的public前加上关键字virtual.
3.那么虚继承是如何解决二义性的呢?
要讨论这个问题,首先要来看看,对于菱形继承和虚继承来说, sizeof(b)的值是多大呢,菱形继承很容易看出答案是20个字节,很多人会想,那虚继承就是16字节了,但经过测试,发现应该是24字节,怎么会多出8个字节呢,这就涉及到内存的分配.
将Test()做修改:
void Test() { D d; d.B::_a = 0; d.C::_a = 1; d._b=2; d._c=3; d._d=4; }
菱形继承中对象d求sizeof(d)=20
可以看到内存分配正好符合菱形继承对象模型中变量的顺序
给class B : public A与class C :public A的public前加上关键字virtual后,变成菱形虚继承,现在来看虚继承的情况.
此时对象d的sizeof(d)=24
那么地址0X00BBF8CC和0X00BBF9D4中存储的是什么呢?
在去查看内存可以看到0X00BBF8CC和0X00BBF9D4分别存储了一个指针,该指针指向的内存偏移四个字节处存储的分别是十进制值20和12,通过观察0X00BBF8CC和0X00BBF9D4与0X00BBF8E0相差的字节数,刚好是20和12,因此,该值代表了偏移量。
相关文章推荐
- 通过菱形继承剖析虚继承解决二义性和数据冗余问题
- 1:分析菱形继承的问题。 2:剖析虚继承是怎么解决二义性和数据冗余的。
- 剖析C++是如何解决菱形继承的二义性和数据冗余的
- 【编程语言】如何解决菱形继承问题
- 菱形继承问题分析及其在C++的解决方法(虚继承)
- 菱形继承,二义性和数据冗余
- 菱形继承产生的问题及解决
- 菱形继承二义性解决方法--虚拟继承
- C++学习笔记(9)——使用范围运算符解决继承中的二义性问题
- CSS3中的opacity透明度属性的继承问题如何解决
- 多重继承引发的二义性问题及解决方法分析
- 什么是菱形继承带来的二义性问题
- c++菱形继承产生的问题及解决
- 请求帮助:如何解决烦人的VS.NET2003编译时“无法将程序集复制到文件,另一个程序正在使用,进程无法访问”的问题?
- 如何解决页面之间传输中文乱码的问题
- ASP.NET如何解决页面之间传输中文乱码的问题
- 如何解决ASP.NET中中文不能正常显示问题?
- 如何解决ASP.NET中中文不能正常显示问题?
- 如何解决一个小问题:当前不会命中断点
- 事务死锁的问题如何解决?