C++中关于菱形继承
来源:互联网 发布:知乎社区 官网 编辑:程序博客网 时间:2024/06/10 01:56
C++中的继承体系,有单继承、多继承、还有复杂的菱形继承,今天我们只讨论菱形继承,以及菱形继承存在的问题,最后我们针对问题给出解决方案。
(1)什么是菱形继承?
顾名思义,菱形继承就是,几个类的继承关系呈菱形状。为此,我们举例解释:
题目:有4个类,Person类、Student类、Teacher类、Assistant类,Student、Teacher继承Person,Assistant继承Student、Teacher。
具体继承关系,以及菱形继承对象模型如下图:
由以上两个图和各个类中的成员,我们会发现菱形继承存在一定的问题:
(1)当创建一个D的对象d时,由于D同时继承了B,C,而B,C都有从A继承过来
的成员_name,即我们要对d中的_name操作时,无法判断是B,C谁的成员,这个问题叫做
菱形继承的二义性
(2)假如说,A中的某一个成员被B,C继承之后,就想当成同一个变量使用,那么
就会有同一个变量才B,C存了2份的情况,这就造成了空间浪费,这个问题就
称为菱形继承的数据冗余
解决二义性的问题倒是有个简单的办法,就是在访问具体变量的时候,前面加上作用域解析符(::),但是要想同时解决二义性,数据冗余,我们提出一个另外一个方法,即虚继承;虚继承就是在有争议的变量的类的继承体系中,继承方式关键字前面加关键字virtual;本例中,就是Student、Teacher虚继承Person
那么,虚继承是怎么解决以上问题呢?
为了简单明了解释这个问题,我们再举个例子:4个类,A类,B类,C类,D类,继承关系如下图:
以上几个类继承的代码实现如下:
#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;d.b=3;d.c=4;d.d=5;cout<<"q"<<endl;}int main(){test();return 0;}通过对比正常的菱形继承,加了虚继承之后D对象d内存情况,我们发现经过虚继承之后,类A中之前那个有争议的成员变量,不在分别自B,C中各存一份,而是在B,C中
都存了一份神秘的地址,在地址里存了这个成员变量的相对偏移量,通过这个偏移量即可找到这个公共的成员变量a;另外,虚继承之后,给公共的成员变量赋值,最后一个有效;以下是验证结果图(图1为没有虚继承的d的内存;图2为有虚继承的d的内存)
图1 图2
- C++中关于菱形继承
- c++-关于菱形继承&虚继承的问题总结
- 【C++】菱形继承
- 【c++】菱形继承
- 【c++】菱形继承
- 【C++】继承(菱形继承)
- <c++>继承及菱形继承
- 【C++】菱形继承与虚拟菱形继承的对比分析
- C++:菱形继承和虚拟继承
- CPP基础知识—关于菱形继承
- (C++)继承、菱形继承和虚继承的那些事儿
- 【C++】菱形虚拟继承(内存布局)
- 【c++】菱形虚拟虚拟继承模型探索
- C++: 虚表和菱形虚拟继承
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- PHP中安装redis扩展
- robolectric完全解析
- 66. Plus One(java)
- 二分查找模板C++
- HTML5 LocalStorage本地存储和sessionStorage使用
- C++中关于菱形继承
- 动态规划-钢条切割问题
- java 双重检查加锁弊端
- Android引用Library的若干问题(全都是坑啊,一定要注意了)
- 使用线程池ExecutorService实现并行查询
- 抽象类和接口
- java基础之final关键字
- Zeppelin源码分析-Interpreter 相关类(3)
- 位运算