关于C++菱形继承问题的解决

Posted codeCJ的日常

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于C++菱形继承问题的解决相关的知识,希望对你有一定的参考价值。

||||||||||||||||||||||||||||||||| 大家好啊 ||||||||||||||||||||||||||||||||||||||

鸽了挺久也挺不好意思,其实主要是上半年太懒了没想写,而且我脸皮厚kjhajhb,啊咳咳!嗯!(严肃脸),那么回归正题啊,众所周知,C++是门面向对象编程的语言,而且C++支持一个子类继承自多个父类,子类就会拥有与父类相同的成员属性和方法。

但在有的编程中啊,大家就有可能会碰到子类所继承的多个父类中,又继承自同一个父类,例如下方的代码示例:

//爷爷类class grandFather {public: int A;};//父类1class Father1 :public grandFather {};//父类2class Father2 :public grandFather {};//让子类继承两个父类class Son :public Father1, public Father2 {};
从上面的代码可以看到,两个父类同时继承了相同的爷爷类,而子类又继承了那两个父类,也就是说子类中也会有一个名为A的成员属性,那么我们可以对子类进行一下测试,使用一下其名为A的成员属性:
 Son s; s.A = 100;

出乎意料的是,在使用子类中的成员属性A时,报错了!报错内容如下:





我们刚说过: 子类会拥有与父类相同的成员属性和方法。 那么也就是说子类继承了两个父类中的成员属性 A ,也就是子类中有两个相同名称的成员属性A,我这么说可能不是很清楚,给大家看一下子类的结构图吧:

关于C++菱形继承问题的解决

上图简化后如下图所示:

可以看出Son类里有两个相同名称的成员属性A,一个继承自Father1类,另一个继承自Father2类,虽然我们可以在使用的时候进行一下访问区分:如s.Father1::A。但是在实际开发中,我们只需要一个就够了,并不需要两个相同的成员属性,而且多出来的成员属性还多占一份内存空间,有种占着茅坑不拉*的感觉。

***那么问题来了,怎么能解决这个问题呢?

答案就是:进行虚继承,让父类所继承的类变为虚基(父)类!

改后代码如下:

//爷爷类class grandFather {public: int A;};//父类1class Father1 :virtual public grandFather {};//父类2class Father2 :virtual public grandFather {};//让子类继承两个父类class Son :public Father1, public Father2 {};
父类在继承爷爷类时加上virtual关键字之后,爷爷类成为虚基类,孙子类在继承父类时,会继承父类的虚基类指针(并么有继承数据),而虚基类指针指向了一个虚基类表,表中记录了一个数据,该数据为偏移量,孙子类在访问继承来的数据时,会通过虚基类指针所指向的虚基类表中的偏移量找到其父类所继承的爷爷类的数据,保证了成员的唯一性。

图示如下:


感慨:C++多少有点掉发。

以上是关于关于C++菱形继承问题的解决的主要内容,如果未能解决你的问题,请参考以下文章

C++虚继承解决菱形继承的问题细节

C++虚继承解决菱形继承的问题细节

C++虚继承解决菱形继承的问题细节

C++菱形继承问题与虚拟继承原理

C++菱形继承问题与虚拟继承原理

C++继承详解