当前位置: 首页 > news >正文

【C++】继承 ⑫ ( 继承的二义性 | virtual 虚继承 )

文章目录

  • 一、继承的二义性
    • 1、场景说明 - 继承的二义性
    • 2、继承中的二义性报错
    • 3、完整代码示例
  • 二、virtual 虚继承
    • 1、虚继承引入
    • 2、虚继承语法
    • 3、代码示例 - 虚继承





一、继承的二义性




1、场景说明 - 继承的二义性


A 类 是 父类 ,

B 类 和 C 类 继承 A 类 , 是 子类 ,

D 类 多继承 B 类 和 C 类 , 是 孙子类 ;


在这里插入图片描述

假如 A 类中有 成员变量 x ,

则 子类 B 类 和 C 类 都会继承该 成员变量 x ,

D 类 多继承 B 类 和 C 类 , 会 分别从 B 和 C 各自 继承一个 成员变量 x ;

D 类中 , 从 B , C 两个父类中继承自 爷爷类 A 的成员变量 , 会出现二义性 ;


代码如下 :

#include "iostream"
using namespace std;class A {
public:int x;
};// 子类 B 继承了父类 A 的 x 成员
class B : public A {
public:int y;
};// 子类 C 继承了父类 A 的 x 成员
class C : public A {
public:int z;
};// D 多继承 B 和 C 
// 分别从 B 和 C 各自继承一个来自 A 的成员 x
class D : public B, public C {
public:int k;
};

2、继承中的二义性报错


如果强行使用 对象.x 访问继承自 A , 会报错 error C2385: 对“x”的访问不明确 ;

定义 D 类的对象 d , 如果访问 继承自 A 类的 x 成员 , 则会出现二义性 ;

	// 定义 D 类对象 dD d;// 访问 继承自 A 类的 x 成员出现二义性// 报错 error C2385: 对“x”的访问不明确d.x = 40;

完整报错信息 :

1>------ 已启动生成: 项目: HelloWorld, 配置: Debug Win32 ------
1>Test.cpp
1>Test.cpp(41,6): error C2385: 对“x”的访问不明确
1>Test.cpp(41,6): message : 可能是“x”(位于基“A”中)
1>Test.cpp(41,6): message : 也可能是“x”(位于基“A”中)
1>已完成生成项目“HelloWorld.vcxproj”的操作 - 失败。
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0==========

3、完整代码示例



代码示例 :

#include "iostream"
using namespace std;class A {
public:int x;
};// 子类 B 继承了父类 A 的 x 成员
class B : public A {
public:int y;
};// 子类 C 继承了父类 A 的 x 成员
class C : public A {
public:int z;
};// D 多继承 B 和 C 
// 分别从 B 和 C 各自继承一个来自 A 的成员 x
class D : public B, public C {
public:int k;
};int main() {// 定义 D 类对象 dD d;// 访问继承自 B 类的 y 成员d.y = 10;// 访问继承自 C 类的 z 成员d.z = 20;// 访问 D 类自己的成员 kd.k = 30;// 访问 继承自 A 类的 x 成员出现二义性// 报错 error C2385: 对“x”的访问不明确//d.x = 40;// 控制台暂停 , 按任意键继续向后执行system("pause");return 0;
}

执行结果 :

在这里插入图片描述





二、virtual 虚继承




1、虚继承引入


在多继承中 , 如果一个类继承了多个含有相同基类的派生类 , 就会产生菱形继承结构 ;

这种情况下 , 可能会出现多个不同的基类实例 , 导致重复定义和二义性 ;

为了应对上述 继承的二义性 问题 ,

C++ 语言 使用 " 虚继承 " 解决 继承中的 二义性问题 ;


C++ 中的 " 虚继承 " 是一种解决 多继承 带来的 菱形问题(diamond problem)的技术 ;

虚继承的目的是 确保每个基类只被继承一次 , 从而避免 重复定义 和 二义性等问题 ;


虚继承 通过在 派生类 中使用关键字 virtual 来指示基类应该被虚继承 , 虚继承确保了每个基类只被继承一次 , 从而避免了重复定义和二义性 ;

在 C++ 中,使用虚继承的语法是在基类列表中使用 virtual 关键字 ;


2、虚继承语法


虚继承语法 : 在 继承的 访问限定符 之前 , 添加 virtual 关键字 , 将该继承行为定义为 " 虚继承 " ;

class 子类类名 : virtual 访问限定符 父类类名
{// 子类内容
}

下面的 B 类 和 C 类 , 就是 虚继承 类 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;
};

3、代码示例 - 虚继承


代码示例 :

#include "iostream"
using namespace std;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;
};int main() {// 定义 D 类对象 dD d;// 访问继承自 B 类的 y 成员d.y = 10;// 访问继承自 C 类的 z 成员d.z = 20;// 访问 D 类自己的成员 kd.k = 30;// 访问 继承自 A 类的 x 成员出现二义性// 报错 error C2385: 对“x”的访问不明确// 使用 virtual 虚继承后 , 不会报错d.x = 40;// 控制台暂停 , 按任意键继续向后执行system("pause");return 0;
}

执行结果 :

在这里插入图片描述

http://www.lryc.cn/news/206323.html

相关文章:

  • Linux网络流量监控iftop
  • 【虚幻引擎UE】UE4/UE5 基于2D屏幕坐标获取场景3D坐标 射线检测(蓝图/C++)
  • 【OpenHarmony】系统编译环境搭建笔记
  • 深入理解JVM虚拟机第十二篇:JVM中的线程说明
  • synchronized 、ReentrantLock
  • 用VSCODE启动Java项目
  • 最简单的修改linux系统上Docker的镜像源
  • layui移除(删除)table表格的一行
  • 67 跳跃游戏 II
  • 客户中心模拟(Queue and A, ACM/ICPC World Finals 2000, UVa822)rust解法
  • 方案聚焦:高可用的F5分布式云DNS负载均衡
  • 大数据性能测试方案-V1.0
  • Kafak - 单机/集群快速安装指北(3.x版本)
  • 互联网Java工程师面试题·Spring篇·第五弹
  • XTU-OJ 1221-Binary
  • Chromium源码由浅入深(三)
  • 如何集成验证码短信API到你的应用程序
  • Linux- 由映射文件I/O问题引出的SIGBUS 空洞文件(Sparse File)
  • 代码随想录图论 第二天 | 695. 岛屿的最大面积 1020. 飞地的数量
  • R语言代码示例
  • ESP32网络开发实例-将 ESP32 连接到 EMQX Cloud MQTT Broker
  • 基于Kubesphere容器云平台物联网云平台Devops实践
  • 淘宝商品详情页API接口|tb获取商品主图接口
  • JAVA面试笔记
  • 尚硅谷Flume(仅有基础)
  • JS中this的绑定规则
  • 酷开科技 | 酷开系统大屏电视,打造精彩家庭场景
  • GDPU 数据结构 天码行空6
  • 机器学习实验三:决策树-隐形眼镜分类(判断视力程度)
  • 广州华锐互动:VR技术应用到工程项目施工安全培训的好处