参考资料:4.78 虚继承的详解_哔哩哔哩_bilibili
C++多重继承详解:优缺点分析与实用示例_c++多继承的优点和缺点-优快云博客
定义
多重继承是C++提供的一种强大的特性,使得一个派生类可以继承多个基类。
class ClassA {
public:
void functionA() {}
};
class ClassB {
public:
void functionB() {}
};
class ClassC : public ClassA, public ClassB {};
多继承的优点
代码复用:派生类可以继承多个基类,从而重用基类中的代码和功能。
丰富的接口:派生类可以同时调用多个基类中的方法和属性,从而拥有更丰富的接口。
多继承的缺点
二义性问题:当多个基类中有同名的成员时,派生类对象调用这些成员会出现二义性。
class Base1 {
public:
void func() {}
};
class Base2 {
public:
void func() {}
};
class Derived : public Base1, public Base2 {};
int main(){
Derived d;
d.func();//报错,不知道是哪个基类里的func函数
}
复杂的内存模型:多重继承带来复杂的内存结构,尤其是当多个基类之间有共同的父类时,需要额外处理重复基类对象问题。
解决多重继承问题的方法
全局作用域解析:通过指定基类名前缀,明确调用哪个基类的成员。
//上述代码,指定作用域就会让编译器知道是哪个基类的函数
d.Base1::func();//Base1里的func函数
虚拟继承:使用虚拟继承确保从多个路径继承的同一基类只存在一个实例,从而避免重复实例和二义性问题。
虚继承
virtual修饰继承方式,虚继承没有节约空间
class Animal{
public:
int data;
};
//Sheep虚继承Animal,Animal是虚基类
class Sheep:virtual public Animal{
public:
};
class Tuo:virtual public Animal{
public:
};
class SheepTuo:public Sheep,public Tuo{
public:
};
int main(){
SheepTuo s;
s.data=200;
}
只要是虚继承,就会产生虚基类指针(vbptr) 和虚基类表(vbtable) v(virtual) b(base) ptr(指针)
vbptr指向虚基类表,虚基类表里存放当前虚指针和对于虚基类的首地址的偏移量
之所以产生vbptr和vbtable目的保证不管多少个继承,虚基类的数据只有一份
Sheep和Tuo虚继承时,不会继承数据,而是会产生一个ptr,描述ptr为了找到这个数据偏移量是多少,而SheepTuo继承他俩时,也只会继承他俩的指针和虚基类表,只要对偏移量稍稍修改,他也能访问到那块数据