当我们谈到C++时首先会想到什么?我想大多数会想到C++的三大特性,封装,继承,多态。今天我们就浅谈一下菱形虚拟继承。
我们要谈菱形继承,首先要弄明白什么是菱形继承,它的作用是什么。
菱形继承:两个子类继承同一个父类,而又有子类同时继承这两个子类。例如:
#define _CRT_SECURE_NO_WARNINGS 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;};int main(){ D d; d._a = 1; system("pause"); return 0;}分析上面代码,运行会发生什么情况?为什么会发生这种情况呢?
两个子类继承了同一个基类,又有子类分别继承了这两个子类;当创建一个D类对象d,当调用_a时编译器不知道要调用B中的_a,还是C中的_a。这个就是菱形继承的二义性(java就不会存在这种情况,因为java只支持单继承)。为了解决这个问题我们可以使用::明确给哪个_a赋值。
D d;d.B::_a = 1;d.C::_a = 2;除此上面方法,C++还提供了另一种方法-----虚继承;//菱形继承 D d; d.B::_a = 0; d.C::_a = 1; d._b = 2; d._c = 3; d._d = 4;//菱形虚拟继承 D d; d._a = 1; d._b = 2; d._c = 3; d._d = 4;例如以上代码,我们可以通过比较菱形继承和菱形虚拟继承:
通过比较分析菱形对象模型,我们可以看出菱形虚拟继承在底层加了四个字节存放到A的偏移量,通过偏移量可以完美解决菱形继承的二义性和它的另一个主要问题--数据冗余。
新闻热点
疑难解答