news 2026/8/21 6:08:10

多继承与虚基类

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
多继承与虚基类

多继承派生类的语法格式:

class 派生类名 : <继承方式1> 基类名1,

<继承方式2> 基类名2,

…… {

……//派生类新添加的成员

};

多继承派生类对象的构造和析构:

派生类名(参数表):基类名1(参数表1),

基类名2(参数表2),

对象成员1(参数表3),

对象成员2(参数表4),

… {

//派生类新添加的成员

}

派生类构造执行顺序是按照:基类对象、成员对象、普通变量的高到低优先级执行的,其中其中基类对象的调用顺序和声明继承关系的顺序有关。

但是析构函数的执行顺序与之相反,先调用派生类的析构函数,再调用对象成员的析构函数,最后调用基类的析构函数。

访问不同基类同名成员时的二义性

class A{ public: int value; void f(){}; }; class B{ public: int value; void f(){}; void g(){}; }; class C: public A, public B{ public: void g(){}; void h(){}; }; int main(){ C C1; C1.f(); C1.value=9; return 0; }

这里在调用f()和value时会出现二义性,因为编译器不知道你访问的是A和B中的哪一个()和value。

所以在此我们需要填写他的“绝对路径”,类名对成员加以限定:改成:

int main(){
C C1;
C1.A::f();
C1.A::value=9//访问A的f()和value。
return 0;
}

第二种情况:

class A{ public: int a; void g( ){}; }; class B1: public A{ int b1; }; class B2: public A{ int b2; }; class C: public B1, public B2{ int c; public: int f(){}; }; int main(){ C Cobj; Cobj.a=8; Cobj.A::a=9; Cobj.g( ); return 0; }

这一二义性的冲突是因为B1、B2都有一个公共基类A,这个公共基类会在派生类对象中产生两个基类子对象,于是我们也要来对此进行限定:

Cobj.B1::a=9;或 Cobj.B2::a=9;

但是这还有一个问题,使用绝对路径找到的基类,我们也可以得知派生类对象中存在多个基类对象的拷贝,导致空间浪费,解决方法也很简单,将A设为虚基类即可,这样 B1 和 B2 继承 A 时,C 最终只会保留一份 A 的子对象,就不会有二义性了。

虚基类

虚基类子对象被合并成一个子对象,这种“合并”作用,使得可能出现的二义性被消除。下面是使用虚基类与没使用虚基类的概念图:

class A { public: int a = 10; void g() { cout << "A的g()函数,a=" << a << endl; } }; // B1虚继承A class B1 : virtual public A {}; // B2虚继承A class B2 : virtual public A {};

虚基类构造函数的调用次序有着自己独特的次序,规则:

1:对于最终派生类来说,虚基类的构造必须在非虚基类之前调用;

2:同一个层次中包含多个虚基类,那么按照虚基类构造函数按它们说明的次序调用。

若虚基类由非虚基类派生,则遵守先调用基类构造函数,再调用派生类构造函数的规则。

举个栗子:

class base{…}; class bas2{…}; class level1 : public base2, vitrual public base{…}; class level2 : public base2, vitrual public base{…}; class toplevel : public level1, vitrual public level2{…};

声明toplevel 时,构造顺序是从 “最顶层虚基类” 开始,再到 “普通基类 / 中间类”,最后到自身

第一步,先调用全局虚基类

base被level1、level2都虚继承了,所以base是全局虚基类,会被优先构造且只构造 1 次→ 顺序第 1 位:base

第二步,按照规则优先调用虚基类

level2是toplevel的虚基类,所以要先构造level2(规则1),而构造level2时,要先构造它的基类:
level2的基类:base2(普通,先构造) + base(虚基类,已经构造过了,不再构造)(规则2
→ 顺序第 2-3 位:base2(level2 的普通基类) → level2

第三步

level1是toplevel的普通基类,构造level1时,要先构造它的基类:
level1的基类:base2(普通,先构造) + base(虚基类,已构造)(规则2
→ 顺序第 4-5 位:base2(level1 的普通基类) → level1

第四步

最后构造toplevel→ 顺序第 6 位:toplevel

综合

base(全局虚基类)→ base2(level2 的普通基类)→ level2(toplevel 的虚基类)→ base2(level1 的普通基类)→ level1(toplevel 的普通基类)→ toplevel

例2:

class base{…}; class base2{…}; class level1 : virtual public base2, virtual public base{…}; class level2 : virtual public base2, virtual public base{…}; class toplevel : public level1, virtual public level2{…};

同样的道理,但不同的是level1和level2都是虚基类。

此时base与base2都是全局变量,当有多个全局虚基类时,构造顺序遵循:
最终派生类继承链中,虚基类首次出现的 继承声明顺序排序。

最终派生类toplevel的继承链中,base2和base首次出现在level1、level2的继承声明里,且声明顺序是base2在前、base在后 → 先构造base2,再构造base。所以按照构造顺序定下base2为第一位,basee为第二位。

再通过规则1优先构造toplevel的虚基类level2为第三位,再构造普通类level1为第五位,最后构造自身toplevel。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/22 0:18:37

无需训练数据:EmotiVoice零样本克隆背后的黑科技揭秘

无需训练数据&#xff1a;EmotiVoice零样本克隆背后的黑科技揭秘 在AI语音助手越来越“懂人心”的今天&#xff0c;我们是否还满足于千篇一律的机械音&#xff1f;当智能音箱用你母亲的声音温柔地读出睡前故事&#xff0c;当游戏角色因剧情转折突然语气颤抖、愤怒爆发——这些不…

作者头像 李华
网站建设 2026/8/22 1:54:00

fabric思维链技术终极指南:让AI推理过程一目了然

fabric思维链技术终极指南&#xff1a;让AI推理过程一目了然 【免费下载链接】fabric fabric 是个很实用的框架。它包含多种功能&#xff0c;像内容总结&#xff0c;能把长文提炼成简洁的 Markdown 格式&#xff1b;还有分析辩论、识别工作故事、解释数学概念等。源项目地址&am…

作者头像 李华
网站建设 2026/8/21 18:45:47

Agent服务日志追踪实战(从入门到精通的3大核心方法)

第一章&#xff1a;Agent服务日志追踪的核心价值与挑战在分布式系统架构日益复杂的背景下&#xff0c;Agent作为数据采集与执行调度的关键组件&#xff0c;其运行状态的可观测性直接决定了系统的稳定性与故障响应效率。日志追踪不仅是诊断Agent异常行为的基础手段&#xff0c;更…

作者头像 李华
网站建设 2026/8/21 22:59:57

【量子编程效率翻倍秘诀】:为何顶尖工程师都在用VSCode做电路渲染?

第一章&#xff1a;量子编程效率翻倍的底层逻辑量子计算的核心优势在于其并行处理能力&#xff0c;源于叠加态与纠缠态的物理特性。传统二进制位只能表示0或1&#xff0c;而量子比特&#xff08;qubit&#xff09;可同时处于0和1的叠加状态。这一特性使得量子程序在执行某些算法…

作者头像 李华
网站建设 2026/8/21 20:16:58

从零开始:美狐美颜SDK让视频应用瞬间拥有专业美颜能力

从零开始&#xff1a;美狐美颜SDK让视频应用瞬间拥有专业美颜能力 【免费下载链接】Meihu-Beautyface-sdk 美狐美颜sdk&#xff0c;支持美颜滤镜(Beauty Filter)、面具特效(Mask the special effects)、贴纸(Software/Hardware Encoder) 、滤镜(LUTs) 项目地址: https://gitc…

作者头像 李华
网站建设 2026/8/21 0:58:30

ChatTTS-ui音色定制实战指南:从基础配置到专业级语音包开发

ChatTTS-ui音色定制实战指南&#xff1a;从基础配置到专业级语音包开发 【免费下载链接】ChatTTS-ui 匹配ChatTTS的web界面和api接口 项目地址: https://gitcode.com/GitHub_Trending/ch/ChatTTS-ui 你是否曾经遇到过这样的困境&#xff1a;想要为你的应用添加独特的语音…

作者头像 李华