【C++】继承 ⑬ ( 虚继承原理 | 虚继承解决继承二义性问题 | 二义性产生的原因分析 )

news2024/7/2 4:15:07

文章目录

  • 一、虚继承原理
    • 1、虚继承解决继承二义性问题
    • 2、二义性产生的原因分析
    • 3、虚继承原理
  • 二、代码示例 - 虚继承原理
    • 1、完整代码示例
    • 2、执行结果





一、虚继承原理




1、虚继承解决继承二义性问题


继承的二义性 : 如果 一个 子类 ( 派生类 ) 继承多个 父类 ( 基类 ) , 这些父类 都继承了 相同的父类 , 那么 子类 访问 父类的父类 中的成员 , 就会产生 二义性 ;

  • 报错 : error C2385: 对“x”的访问不明确 ;

使用 " 虚继承 " 可以解决上述问题 , 子类 继承父类时 , 在 访问限定符 之前使用 virtual 关键字 , 即可将 普通继承 改为 虚继承 ;

  • 下面的代码中 A 是父类 ;
  • B 类 和 C 类 虚继承 A 类 , 这样当 某个类 同时 多继承 B 类 和 C 类时 , 访问 A 类中的成员时 , 不会出现 二义性 ;
  • 由于 B 和 C 虚继承 A , D 类访问 A 中的成员 , 不会产生二义性 ;
class A {
public:
	int x;
};

// 子类 B 继承了父类 A 的 x 成员
class B : virtual public A {
public:
	int y;
};

// 子类 C 继承了父类 A 的 x 成员
class C : virtual public A {
public:
	int z;
};

// D 多继承 B 和 C 
// 分别从 B 和 C 各自继承一个来自 A 的成员 x
class D : public B, public C {
public:
	int k;
};

2、二义性产生的原因分析


二义性产生的原因 :

  • 如果 上述 B 和 C 类 没有 虚继承 A 类 ;
  • 上述 D 对象 创建时 , 会调用 两次 A 的构造函数 , 一次由 B 对象调用 , 一次由 C 对象调用 ;
  • 此时 D 对象中就包含了 两个 A 类的 子对象 ;
  • 当 访问 A 类的成员时 , 不知道访问哪个 A 类的成员 , 就出现了二义性 ;

3、虚继承原理


使用 虚继承 后 , 在调用 虚继承 父类 构造函数时 , 只调用一次 ;


构建 D 类对象的 流程 如下 :

  • 先构建 B 类对象 , 调用了一次 A 的构造函数 , 构造了 A 类子对象 ;
  • 再构建 C 类对象 , 发现已经调用了一次 A 的构造函数 , 不会再次构造 第二个 A 类子对象 ;

只有一个 A 类子对象 , 这样就避免了 二义性 的产生 ;





二、代码示例 - 虚继承原理




1、完整代码示例


在下面的代码中 ,

为 A 类 , B 类 , C 类 , D 类 , 都定义一个默认的 无参构造函数 ,

每个构造函数 中打印相关信息 ;

B 类 和 C 类都 虚继承 A 类 ,

最终构建 D 类使 , 发现 A 类的构造函数只调用了一次 , 这样避免了 二义性产生 ;


代码示例 :

#include "iostream"
using namespace std;

class A {
public:
	int x;
	A()
	{
		cout << "A 构造函数" << endl;
	}
};

// 子类 B 继承了父类 A 的 x 成员
class B : virtual public A {
public:
	int y;
	B()
	{
		cout << "B 构造函数" << endl;
	}
};

// 子类 C 继承了父类 A 的 x 成员
class C : virtual public A {
public:
	int z;
	C()
	{
		cout << "C 构造函数" << endl;
	}
};

// D 多继承 B 和 C 
// 分别从 B 和 C 各自继承一个来自 A 的成员 x
class D : public B, public C {
public:
	int k;
	D()
	{
		cout << "D 构造函数" << endl;
	}
};

int main() {

	D d;

	d.x = 10;

	// 控制台暂停 , 按任意键继续向后执行
	system("pause");

	return 0;
}

2、执行结果


执行结果 : A 类的构造函数只调用了一次 , D 类中只有一个 A 类子对象 , 避免了二义性产生 ;

A 构造函数
B 构造函数
C 构造函数
D 构造函数
Press any key to continue . . .

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1137036.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【【萌新的FPGA学习之FIFO的介绍】】

萌新的FPGA学习之FIFO的介绍 FIFO first in first out FIFO 的作用更多的是 缓冲与缓存 或者FIFO 也常被用来使用为 FIFO 本质上是由 RAM 加读写控制逻辑构成的一种先进先出的数据缓冲器&#xff0c;其与普通存储器 RAM 的 区别在于 FIFO 没有外部读写地址线&#xff0c;使用起…

接口自动化测试方案

1、引言 1.1 文档版本 版本 作者 审批 备注 V1.0 XXXX 创建测试方案文档 1.2 项目情况 项目名称 XXX 项目版本 V1.0 项目经理 XX 测试人员 XXXXX&#xff0c;XXX 所属部门 XX 备注 1.3 文档目的 本文档主要用于指导XXX-YY项目常用接口自动化测试…

数据隐私保护与合规性:现代企业的数据安全策略

第一章&#xff1a;引言 在当今数字化时代&#xff0c;数据已经成为企业最宝贵的资源之一。然而&#xff0c;伴随着大规模数据收集和处理的增加&#xff0c;数据隐私保护和合规性问题也日益凸显。本文将深入探讨数据隐私保护和合规性对现代企业的重要性&#xff0c;并提供一些…

重大突破!国内首个ASIL D认证MCU在底盘域量产上车

中国本土车规级MCU再次实现了重要突破。 近日&#xff0c;芯驰科技的高性能车规MCU——E3搭载在明然科技悬架控制器&#xff08;CDC&#xff09;批量下线&#xff0c;并且成功在奇瑞瑞虎9、星途瑶光等车型上正式量产&#xff0c;成为了国内首个应用在主动悬架的车规控制芯片。…

行业追踪,2023-10-26

自动复盘 2023-10-26 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

干货很干:5个有效引流方法,让客户找上门

如何才能把用户引流到私域&#xff1f;是很多老板&#xff0c;店主&#xff0c;线上创业者的卡点&#xff0c;今天分享5个实用方法&#xff1a; ✅线下导流 ✅巧用搜索 ✅同行互推 ✅社群引流 ✅内容输出 所以引流不仅需要知道方法&#xff0c;还需要知道底层逻辑&#xff0c;也…

分布式事务(Seata)——Seata分布式事务XA模式、AT模式、TCC模式的介绍和对比 结合案例分析AT模式和XA模式【源码】

前言 事务(TRANSACTION)是一个不可分割的逻辑单元&#xff0c;包含了一组数据库操作命令&#xff0c;并且把所有的命令作为一个整体向系统提交&#xff0c;要么都执行、要么都不执行。 事务作为系统中必须考虑的问题&#xff0c;无论是在单体项目还是在分布式项目中都需要进行…

从零开始:开发知识付费小程序的入门指南

当下&#xff0c;知识付费小程序成为了一个独具潜力的领域。本篇文章将为您提供一份从零开始的知识付费小程序开发入门指南&#xff0c;让您能够进入这个领域并开始赚取您的专业知识。 第一步&#xff1a;什么是知识付费小程序&#xff1f; 知识付费小程序是一种基于微信小程…

数据创建与数据管理

原文&#xff1a;Dataset Creation and Curation Introduction to Data-Centric AI 为监督学习创建数据集需要样本以及样本的标签。课程专注于分类任务&#xff0c;但是把这些原理运用到其它监督学习的任务也是可以的。 数据收集 寻找训练数据时的关键问题&#xff1a; 1.…

c#学习相关系列之构造函数

目录 一、构造函数的作用 二、构造函数的特征 三、三种构造函数介绍 1、实例构造函数 2、静态构造函数 3、私有构造函数 一、构造函数的作用 构造函数用来创建对象&#xff0c;并且可以在构造函数中对此对象进行初始化。构造函数具有与类相同的名称&#xff0c;它通常用来…

每日一练 | 网络工程师软考真题Day45

阅读以下说明&#xff0c;答复以下【问题1】至【问题4】 【说明】 某公司有1个总部和2个分部&#xff0c;各个部门都有自己的局域网。该公司申请了4个C类IP地址块 202.114.10.0/24~202.114.13.0/24。公司各部门通过帧中继网络进行互联&#xff0c;网络拓扑结构如图1-1所示。 【…

如何在线去除图片上的水印?一分钟教你一键去除

想要去除图片上的水印&#xff1f;不妨试试在线图片水印去除工具&#xff01;在个人生活或工作中&#xff0c;我们常常需要使用他人的图片&#xff0c;然而图片上的水印却常常成为阻碍&#xff0c;若你正为此烦恼&#xff0c;那么在线图片去水印工具将成为你的救星&#xff0c;…

禁止使用U盘的方法

禁止使用U盘的方法 说到保护电脑数据安全&#xff0c;无论是个人还是企业&#xff0c;这都是一个很重要的问题&#xff0c;大家都会想到设置电脑开机密码&#xff0c;但这还远远达不到我们的要求&#xff0c;有很多种方法可以跳过开机验证&#xff0c;直接进入电脑。所以我们还…

代码随想录Day29 贪心04 LeetCode T860 柠檬水找零 T406 根据身高重建队列 T452 用最少得箭引爆气球

LeetCode T860 柠檬水找零 题目链接:860. 柠檬水找零 - 力扣&#xff08;LeetCode&#xff09; 题目思路: 这道题我们只要顺序按照数组判断是否能有钱找零即可,我们定义三个变量来记录每张钞票目前的数量,其中我们知道给10元得找5元,给二十元得找515元,而15元的组合有10元5元和…

算法通过村第十七关-贪心|青铜笔记|贪心也很简单呕

文章目录 前言难以解释的贪心算法贪心问题发放饼干柠檬水找零分发糖果 总结 前言 提示&#xff1a;我像接纳变甜的果实一般迎接此时。 --朱塞培翁加雷蒂《享受》 贪心的思想很难用理论去解释&#xff0c;这里我们通过案例感受下&#xff0c;怎么思考贪心的问题。 难以解释的贪心…

threejs(5)-详解灯光与阴影

一、Gsap动画库基本使用与原理 npm 地址&#xff1a;https://snyk.io/advisor/npm-package/gsap import * as THREE from "three"; // 导入轨道控制器 import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; // 导入动画库 import…

设备巡检怎么规范流程?如何做好后勤管理工作?

后勤巡检对于企业和高校来说&#xff0c;就像一台电脑上的安全防护软件&#xff0c;它会定期或不定期地扫描和检查系统&#xff0c;找出存在的问题&#xff0c;例如垃圾文件和病毒风险。巡检的目的是为了检查公司和高校的各项设施、设备和环境等&#xff0c;以发现潜在的环境安…

React之服务端渲染

一、是什么 在SSR中 (opens new window)&#xff0c;我们了解到Server-Side Rendering &#xff0c;简称SSR&#xff0c;意为服务端渲染 指由服务侧完成页面的 HTML 结构拼接的页面处理技术&#xff0c;发送到浏览器&#xff0c;然后为其绑定状态与事件&#xff0c;成为完全可…

【C++】类与对象 第一篇(class,this)

目录 什么是类&#xff1f; 类的引入 class 类的两种定义方式: 声明与定义分离 类的访问限定符号 访问限定符​编辑 C中struct和class的区别是什么? 封装 类的作用域 类的实例化 类对象模型 如何计算类对象的大小 this指针 C语言和C实现Stack的对比 C语言实现…

程序员新手村常见问题

到今年已经工作十一个年头了&#xff0c;把这些年自己出现在自己身上或者同事身上的问题记录下来。 手里有锤子&#xff0c;看神马都是钉子 新人程序员很容易手段目的化&#xff0c;战术战略化。学了一门新技术后&#xff0c;不管具体的技术场景&#xff0c;哪里都想拿出来比…