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::a
和C::a
的a就是唯一的一份,可以直接通过D::a
访问。这里的A被称为虚基类。
B、C中原本重复的数据变成了虚基类表指针,该指针指向了一个虚基类表,虚基类表中存储了该指针到公共数据所在内存的偏移量。
注:公共数据的位置可能是D的开头,也可能是结尾,依编译器而定
简单来说:
- 如果使用非虚拟继承,那么D会从B、C那里继承两份相同的数据。
- 如果使用虚拟继承,那么那两份相同的数据在D类对象中只会存在一份。而D从B、C那里继承的是它们独有的数据以及B和C的虚基类表指针。通过它们各自的虚基类表指针,就可以获取该指针与那份公共数据存储位置的偏移量,进而可以访问它。
注:虚基类表的第一项是该指针与自身的偏移量,即0。第二项是该指针与公共数据的偏移量。
以上是关于C++菱形继承问题与虚拟继承原理的主要内容,如果未能解决你的问题,请参考以下文章
8-5:C++继承之多继承,菱形继承,虚继承,虚基表,继承和组合