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

Posted 白龙码~

tags:

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

文章目录

菱形继承与虚拟继承

多个类继承了同一个公共基类,而这些派生类又同时被一个类继承,这种称为菱形继承或钻石继承。

多个类继承了同一个公共基类,而这些派生类又同时被一个类继承,这种称为菱形继承或钻石继承

数据冗余问题

B和C同时继承了A的成员,此时D继承B和C,相当于获得了两份A的成员,造成数据冗余。

二义性问题

B和C同时继承了A中的a,然后又派生出了D,因而D中存在两份a:一份是B::a,一份是C::a。因此,在D中直接访问a会导致错误,此时的a就具有二义性,需要指定类作用域才能访问。

虚拟继承解决问题

虚拟继承的意义在于:解决菱形继承中数据冗余和二义性的问题。

class A
public:
	int a;
;
class B :virtual public A
public:
	int b;
;
class C :virtual public A
public:
	int c;
;
class D :public B, public C
	int d;
;

此时D从B、C继承来B::aC::a的a就是唯一的一份,可以直接通过D::a访问。这里的A被称为虚基类

B、C中原本重复的数据变成了虚基类表指针,该指针指向了一个虚基类表,虚基类表中存储了该指针到公共数据所在内存的偏移量

注:公共数据的位置可能是D的开头,也可能是结尾,依编译器而定

简单来说:

  • 如果使用非虚拟继承,那么D会从B、C那里继承两份相同的数据
  • 如果使用虚拟继承,那么那两份相同的数据在D类对象中只会存在一份。而D从B、C那里继承的是它们独有的数据以及B和C的虚基类表指针。通过它们各自的虚基类表指针,就可以获取该指针与那份公共数据存储位置的偏移量,进而可以访问它。

注:虚基类表的第一项是该指针与自身的偏移量,即0。第二项是该指针与公共数据的偏移量。

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

8-5:C++继承之多继承,菱形继承,虚继承,虚基表,继承和组合

C++中的继承

C++之继承总结(继承的定义与格式,赋值转换,默认成员函数,菱形继承及菱形虚拟继承)

继承(C++)

C++继承

继承(C++)