C++-继承:多重继承 && 虚拟继承

本文详细探讨了C++中多重继承的基本概念、成员名的二义性及其解决办法,并介绍了虚拟继承的定义方式及其实现机制,帮助读者理解多重继承与虚拟继承的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、多重继承

1.1、多重继承的概念

单一继承&多重继承

1.2、多重继承方式下成员名的二义性

在多继承下,派生类继承了多个基类的成员,当两个不同基类拥有同名成员时,容易产生命名冲突的问题。

使用类域限定符明确指出调用函数所属的基类,如m.A::f()。

1.3、多重继承的构造函数和析构函数

派生类必须为每个基类的构造函数提供初始化参数,构造函数的调用次序是先基类,再对象成员,最后才是派生类的构造函数。基类构造函数的调用次序与它们被继承时的声明次序相同,与初始化列表中的次序没有关系。

2、虚拟继承

2.1、虚拟继承引入的原因

C++在解析派生类的成员函数调用时,会现在派生类中查找该函数,若找到就确定该函数是派生类的成员函数;如果没有找到,就在基类中查找该成员函数。单继承时,没影响;但多继承时,会产生二义性。
例如:

class A {
};
class B:public A {
};
class C:public A {
};
class D:public B, public C {
};

在类B和类C中有类A的一份拷贝,类D为类B和类C的多重派生,具有这两个类的数据成员和成员函数的一份拷贝。所以类D有类A的两份成员,这样就会在派生类对象的成员解析时产生二义性。尽管可以用所属类来解决,但对一个对象来说有两个不同的函数,容易产生数据不一致。

2.2、虚拟继承的定义方式

利用C++提供的关键字virtual限定继承方式,将公共基类指定为虚基类,就可以是该基类的成员在派生类中只有一份拷贝。

class A {
};
class B: virtual public A {
};
class C: virtual public A {
};
class D:public B, public C {
};

通过对公共基类的虚拟继承,派生类只保留了虚基类的一份成员。

2.3、虚拟继承的构造次序

在虚拟继承下,派生类需要在其构造函数的初始化列表中对虚拟基类进行初始化,以实现虚拟基类对象的初始化。但构造函数的调用次序和非虚拟继承不同:
1、先调用虚基类的构造函数,再调用非虚基类的构造函数;
2、若同一继承层次中包含多个虚基类,就按照它们被继承的先后次序调用。如果某个虚基类的构造函数已经在前面被调用了,就不在被调用。
3、若虚基类由非虚基类派生而来,则先调用虚基类的基类构造函数,再调用虚基类的构造函数。

2.4、虚基类由最终派生类初始化

在没有虚拟继承的情况下,每个派生类的构造函数只负责直接基类的初始化。但是在虚拟继承下,虚基类则由派生类的构造函数负责初始化。
若最终的派生类的构造函数没有明确调用虚基类的构造函数,编译器就会尝试调用虚基类不要参数的构造函数(包括无参和缺省参数的构造函数),如果没有找到就会产生编译错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值