news 2026/7/10 13:41:06

多继承与虚基类

作者头像

张小明

前端开发工程师

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/7/10 9:43:24

小米 MiMo-V2-Flash 快速接入 iFlow-CLI 保姆级教程

教程 1、登录小米开放者平台&#xff0c;并进入控制台&#xff1a;Xiaomi MiMo 开放平台 2、点击左侧“API-Keys”栏&#xff0c;再创建API-Key 3、启动iFlow-CLI&#xff0c;输入指令/auth&#xff0c;选择第三种登录方式&#xff1a;“OpenAI 兼容 API” 4、在base URL输入框…

作者头像 李华
网站建设 2026/7/10 8:08:33

MCP量子编程培训材料深度解析(量子计算时代的职业跳板)

第一章&#xff1a;MCP量子编程认证概述MCP量子编程认证&#xff08;Microsoft Certified Professional in Quantum Programming&#xff09;是微软面向量子计算开发者推出的权威技术认证&#xff0c;旨在验证开发者在Q#语言、量子算法设计与Azure Quantum平台应用方面的专业能…

作者头像 李华
网站建设 2026/7/10 5:27:31

CST通过Save As Protected功能对工程进行加密保护

对外发资料有加密要求的用户&#xff0c;使用Save As Protected功能可以实现既呈现仿真结果&#xff0c;又对结构、材料、端口设置等内容进行加密保护。使用该功能时&#xff0c;需要先要保存一下工程。在保存状态下选择File > Project > Save As Protected,便可打开加密…

作者头像 李华
网站建设 2026/7/10 3:31:39

macOS窗口管理工具深度解析:从新手到专家的进阶指南

macOS窗口管理工具深度解析&#xff1a;从新手到专家的进阶指南 【免费下载链接】open-source-mac-os-apps serhii-londar/open-source-mac-os-apps: 是一个收集了众多开源 macOS 应用程序的仓库&#xff0c;这些应用程序涉及到各种领域&#xff0c;例如编程、生产力工具、游戏…

作者头像 李华
网站建设 2026/7/10 11:11:43

【AI工程化核心突破】:如何用Docker快速部署可扩展的智能Agent集群

第一章&#xff1a;智能 Agent 集群部署的挑战与演进随着分布式系统和人工智能技术的深度融合&#xff0c;智能 Agent 集群在边缘计算、自动驾驶协同、工业自动化等场景中扮演着关键角色。然而&#xff0c;其大规模部署面临诸多挑战&#xff0c;包括异构环境适配、动态负载均衡…

作者头像 李华