C++基础学习之虚基类

C++中虚基类 虚基类虚基类概念虚基类是为了防止多重继承时,“孙辈”派生类派生产生对“爷爷辈”类产生多个冗余的数据而定义的概念。与正常继承自基类的区别如下面图示: A是虚基类,B1和B2虚继承自A,D继承B1和B2,D中的数据就是来自A,B1,B2中的数据而无重复冗余。 而没有使用虚继承,D中的数据就包括了两份A类的数据。虚基类例子#include <iostream> using namespace st 阅读详情

首先来了解下二义性:

其实说白了就是解决多重多级继承造成的二义性问题。例如有基类B,从B派生出C和D,然后类F又同时继承了C和D,现在类F的一个对象里面包含了两个基类B的对象,如果F访问自己的从基类B那里继承过来的的数据成员或者函数成员那么编译器就不知道你指的到底是从C那里继承过来的B对象呢还是从D那里继承过来的B对象。

于是虚基类诞生了,将C和D的继承方式改为虚继承,那么F访问自己从B那里继承过来的成员就不会有二义性问题了,也就是将F对象里的B对象统一为一个,只有一个基类B对象。 二义性的两种情况:

第一种情况是一个类由多个基类派生时,不同基类中的数据成员或成员函数同名,在派生类中使用不同基类中的同名成员时产生二义性。

    第二种情况是当一个派生类由多个基类派生,而这些基类又有一个共同的基类,当对该基类中说明的成员进行访问时,可能出现二义性。

    eg.

#include <iostream>
using namespace std;
class Base1 {	//定义基类Base1
public:
	int var;
	void fun() { cout << "Member of Base1" << endl; }
};
class Base2 {	//定义基类Base2
public:
	int var;
	void fun() { cout << "Member of Base2" << endl; }
};
class Derived: public Base1, public Base2 { //定义派生类Derived
};
int main() {
	Derived d;
	Derived *p = &d;

	//d.var = 1;	//对象名.成员名标识  错误  成员名具有二义性
	//d.fun();	//访问Derived类成员  错误  成员名具有二义性
	
	d.Base1::var = 2;	//作用域分辨符标识
	d.Base1::fun();	//访问Base1基类成员
	
	p->Base2::var = 3;	//作用域分辨符标识
	p->Base2::fun();	//访问Base2基类成员

	return 0;
}

解决二义性问题主要有四种方法:

(1)通过作用域运算符(::)明确指出访问的是哪一个基类中的成员。使用作用域运算符进行限定的一般格式是:

        <对象名>.<基类名>::<成员名> //数据成员

        <对象名>.<基类名>::<成员名>(<参数表>) //成员函数

(2)在子类中定义同名成员(如上两例中c类定义的a和disp函数)。与基类成员同名的派生类成员将屏蔽对基类成员的直接访问(同名隐藏),这就是支配原则。

(3)虚基类。虚基类保证了一个类不能从同一个类中直接继承一次以上。

(4)各基类中的成员各不相同,当然,这不是一个很好的解决办法。

下面重点说明虚基类:

虚基类是对派生类而言,所以,虚基类本身的定义同基类一样,在定义派生类时声明该基类为虚基类即可,就是冠以关键字virtual。

        虚基类的语法格式为:

      class <类名> : virtual <继承方式> <基类名>

         { ...  }

eg.

class Base1: virtual public Base0 {	//定义派生类Base1
public:	//新增外部接口
	int var1;
};

关键字virtual告诉编译器,该基类不管经过多少次派生,在其派生类中只能有该基类的一个拷贝。----虚基类的作用

虚基类及其派生类构造函数小结:

l 建立对象时所指定的类称为最(远)派生类。

l 虚基类的成员是由最(远)派生类的构造函数通过调用虚基类的构造函数进行初始化的。

l 在整个继承结构中,直接或间接继承虚基类的所有派生类,都必须在构造函数的成员初始化表中给出对虚基类的构造函数的调用。如果未列出,则表示调用该虚基类的默认构造函数。

l在建立对象时,只有最派生类的构造函数调用虚基类的构造函数,该派生类的其他基类对虚基类构造函数的调用被忽略。

l 在一个成员初始化列表中同时出现对虚基类和非虚基类构造函数的调用时,虚基类的构造函数先于非虚基类的构造函数的调用。


别再死记硬背了!用Python可视化带你直观理解柯西收敛定理(附NumPy代码) 本文通过Python可视化技术,结合NumPy和Matplotlib,直观展示柯西收敛定理的动态过程。文章提供了完整的代码实现,帮助读者从抽象数学定义过渡到具象理解,特别适合数学学习者和Python开发者。通过热力图和交互式参数探索,读者可以清晰观察数列收敛特性,提升数学分析的学习效率。 阅读详情

相关推荐

蓝桥杯FPGA赛道积分赛

代码如下: 按键驱动 代码如下 按键驱动 代码如下: 顶层文件 按键驱动 数码管驱动 声明:本代码借鉴网络资料,如有侵权和错误请联系作者删除。我是从寒假开始备赛的,由于我基础不行,备赛过程中也是混混呃呃的,备赛效率不高,总体来说备赛不认真,有点拖拉,但是最后我也坚持备赛到了今天,在备赛过程中,即复习了旧的东西,也学到了新的东西,总结起来还是有点收获的,后天北京、天津、河北地区就要进行省赛了,我会全力以赴,不管结果怎么样,尽力就好,最后祝大家都能

weixin_69804913的博客 1983

C++ 虚基类

C++ 虚基类. 虚基类如何解决多重继承的问题.

我是小白呀的博客 1万+

在ArcGIS Pro软件中进行滑坡的敏感性和易发性分析

滑坡的敏感性和易发性分析需要综合地形、水文、地质及环境等多维数据,本文罗列了基于ArcGIS Pro软件进行的一系列可执行分析。

weixin_49609713的博客 1731

C++虚基类

1、为什么要引入虚基类 如果一个派生类是从多个基类派生出来的,而这些基类又有一个共同的基类,则在这个派生类中访问这个共同的基类中的成员时,可能会产生二义性。 比如有以下结构 class B{ protected: int a; public: B( ){ ...} }; class B1: public B{ public: base1( ){...} }; class B2: public B{ public: B2( ){...} }; class D:public B1,pu

xdg15294969271的博客 1万+

【iOS开发】dyld: Symbol not found: ___chkstk_darwin 问题解决

【iOS开发】dyld: Symbol not found: ___chkstk_darwin 问题解决 Xcode 13.2.1 运行到iOS12.x版本上崩溃报错如下:dyld: Symbol not found: ___chkstk_darwin dyld: Symbol not found: ___chkstk_darwin Referenced from: /private/var/containers/Bundle/Application/A424CEFD-51DB-450E-9D62-B8

wm9028的专栏 6563

达梦DCA2023年10月培训及考试总结

本次培训共分三天,培训内容不单单是DCA的单机安装、实例创建、库表操作等,培训内容是把关系型数据库的理论及DM8的产品结合起来讲,很实用。具体的考试则是需要个人大量的线下练习,考试总体而言都是培训讲过的内容,只要用心听,好好练习,哪怕是没有计算机基础的童鞋也能考过。提示:以下是本篇文章正文内容,下面案例可供参考总体而言,本次考试不是很难,用心准备,考前认真听讲,考后多次练习,基本都能通过。

qinjuao的博客 2320

C++虚基类详解

建议:能用单一继承解决的问题就不要使用多继承

Gxy_w的博客 1573

SAP成本控制范围配置全流程:从货币参数到标准层次(附2024最新SPRO路径)

本文详细拆解了SAP成本控制范围(Controlling Area)的完整配置流程,涵盖从货币与估价参数文件定义、参数文件分配到控制范围,再到成本中心标准层次创建等核心步骤。文章提供了2024年最新的SPRO导航路径和实战配置要点,帮助顾问构建稳健、可扩展的管理会计基础架构,并附有常见问题排查指南。

java5的博客 938

最全C++(13)——虚基类和C+,C C++编程基础学习

当一个派生类的两个父类都是由同一个类派生出来的时候,在定义类的时候会发生二义性(内存中会有两份爷爷类)virtual修饰成员方法时叫虚函数,virtual修饰修饰继承方式时叫虚继承。上述代码就是菱形继承的一个典型例子,A中的数据在类D中只有一份。

2401_84976016的博客 418

论文翻译:2024 High-Confidence Computing A survey on large language model (LLM) security and privacy: The

大型语言模型(LLMs),如ChatGPT和Bard,已经彻底改变了自然语言理解和生成。它们具有深度语言理解能力、类似人类的文本生成能力、上下文意识和强大的问题解决技能,使它们在各个领域(例如搜索引擎、客户支持、翻译)中变得不可或缺。同时,LLMs也在安全领域获得了关注,揭示了安全漏洞并展示了它们在安全相关任务中的潜力。本文探讨了LLMs与安全性和隐私的交集。具体来说,我们研究了LLMs如何积极影响安全性和隐私,与它们使用相关的潜在风险和威胁,以及LLMs内部的固有漏洞。

CSPhD-winston的博客 1722

触摸芯片RM1015B基本使用方法

RM1015B触摸芯片使用指南:该芯片采用4通道设计(实际使用3通道),通过I2C接口通信(设备地址0x2B)。硬件设计需注意中断/复位引脚复用,需上拉处理。软件配置包括初始化、中断处理和定时器扫描,通过设置各通道阈值(0-300W)调节灵敏度,值越小越灵敏。调试时可调用rm1015B_debug_func()输出波形数据。典型应用场景包括接近检测和手势识别,中断触发后需在8ms内响应。特别注意不同通道的寄存器映射关系及校准流程,确保检测准确性。

云淡风轻 176

学习笔记(12):C++语言基础视频教程-5.8 虚基类及应用

C++语言基础视频培训课程:本课与主讲者在大学开出的程序设计课程直接对接,准确把握知识点,注重教学视频与实践体系的结合,帮助初学者有效学习。本教程详细介绍C++语言中的封装、数据隐藏、继承、多态的实现等入门知识;主要包括类的声明、对象定义、构造函数和析构函数、运算符重载、继承和派生、多态性实现等。 课程需要有C语言程序设计的基础(可以利用本人开出的《C语言与程序设计》系列课学习)。学习者能够通过...

GuangCZ的博客 227

基于YOLOv8的水果新鲜程度检测系统设计与实现

数据采集与预处理模块:负责收集水果图像数据并进行标注和增强深度学习模型:基于YOLOv8的目标检测模型新鲜度评估模块:根据检测结果评估水果新鲜程度用户界面:提供友好的交互界面系统集成:将各模块整合为完整系统水果新鲜程度检测需要包含多种水果在不同新鲜度状态下的图像数据集。:包含5种常见水果(苹果、香蕉、橙子、葡萄、草莓)在不同新鲜度下的图像包含约8,000张图像,分为新鲜和腐烂两类AgriVision:大型农业图像数据集,包含水果检测和分类任务Fruit-360:包含120种水果的高质量图像。

YOLO 444

学习笔记(26):C++语言基础视频教程-5.8 虚基类及应用

C++语言基础视频培训课程:本课与主讲者在大学开出的程序设计课程直接对接,准确把握知识点,注重教学视频与实践体系的结合,帮助初学者有效学习。本教程详细介绍C++语言中的封装、数据隐藏、继承、多态的实现等入门知识;主要包括类的声明、对象定义、构造函数和析构函数、运算符重载、继承和派生、多态性实现等。 课程需要有C语言程序设计的基础(可以利用本人开出的《C语言与程序设计》系列课学习)。学习者能够通过...

cangersuifeng的博客 152

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

第十二周项目二 摩托车继承自行车和机动车(虚基类)

项目要求 详见贺老师博文:《C++语言基础》实践参考——摩托车继承自行车和机动车 代码如下 #include #include #include using namespace std; enum vehicleStaus {rest, running}; //车辆状态:泊车、行进 class vehicle //车辆类 { protected: int max

绿皮哥布林 564

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【C++学习笔记】虚基类(一)

1.为什么要引入虚基类? 在类的继承中,如果我们遇到这种情况: “B和C同时继承A,而B和C都被D继承” 在此时,假如A中有一个函数fun()当然同时被B和C继承,而D按理说继承了B和C,同时也应该能调用fun()函数。这一调用就有问题了,到底是要调用B中的fun()函数还是调用C中的fun()函数呢?在C++中,有两种方法实现调用: (注意:这两种方法效果是不同的) 使用作用域标识符来唯一...

小浣熊的博客 3万+

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

C++虚基类的作用

虚基类的作用     当一个基类被声明为虚基类后,即使它成为了多继承链路上的公共基类,最后的派生类中也只有它的一个备份。例如:class CBase { };class CDerive1:virtual public CBase{ };class CDerive2:virtual public CBase{ };class CDerive12:public CDerive1,CDerive2{ }

caomiao2006的专栏 3万+

Cpp入门基础

定义命名空间,需要使⽤到namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中 即为命名空间的成员。命名空间中可以定义变量/函数/类型等。namespace本质是定义出⼀个域,这个域跟全局域各⾃独⽴,不同的域可以定义同名变量,所以下 ⾯的rand不在冲突了。C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/ 类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。

2401_86658278的博客 5107

C++学习笔记(10)——虚基类的作用

本博客(http://blog.youkuaiyun.com/livelylittlefish)贴出作者(三二一、小鱼)相关研究、学习内容所做的笔记,欢迎广大朋友指正!          虚基类的作用     当一个基类被声明为虚基类后,即使它成为了多继承链路上的公共基类,最后的派生类中也只有它的一个备份。例如:class CBase { };class CDerive1:virtual publ

学习,思考,记录,分享。 9636

C++学习 对象模型之虚基类,虚基类表,虚基类表指针

1.虚基类 什么是虚基类,虚基类的作用是什么? 首先虚基类是为了解决多继承产生的二义性问题,范例代码如下: #include "stdafx.h" #include <stdio.h> #include <iostream> #include <Windows.h> using namespace std; class Base { public: int ...

u014472011的博客 957

学习知识[置顶] C++学习方式方法

查了好多资料,发明还是不全,干脆自己整理吧,至少保证在我的做法正确的,以免误导读者,也是给自己做个记录吧!     很多人认为C++牛B,学好了可以无敌于天下,我只想说:别天真了,没有一种说法,学习好一种语言就就可以笑傲江湖了,如果这样,为什么大家都不跑来学习C++呢。C++只是一个庞杂一点的语言,请大家别神话它。     学习C++,为什么有很多C++大牛,有各自不同的学习方式,这个人这么学...

weixin_34358092的博客 97

C++虚基类作用

当一个基类被声明为虚基类后,即使它成为了多继承链路上的公共基类,最后的派生类中也只有它的一个备份。例如: class CBase { }; class CDerive1:virtual public CBase{ }; class CDerive2:virtual public CBase{ }; class CDerive12:public CDerive1,CDerive2{ };

u010949971的博客 1204

虚基类及虚基类的定义使用

虚基类 在前面学过的继承过程中,不知道大家有没有想到这种情况:在多继承关系中,如果一个派生类的从两个父类那里继承过来,并且这两个父类又恰恰是从一个基类那里继承而来。那这样就麻烦了,因为你可能继承了两份一样的成员! 这就出现了所谓二义性问题,下面我们展开学习: 先给大家举一个能说明这种多继承的例子吧,笔者我想来想去,想了这么一个例子:以前呢有一个大户人家,起初呢就两口子,男主人掌权,保管着大门钥匙,后来他们有两个儿子,若干年后长大成人,男主人也老了,就把钥匙又配了两把,分别交给他的两个儿子,交由他们主持

m0_60226024的博客 4681

C++:虚基类详解

 今天学习多继承时,遇到二义性的问题,然后找到了回答很详细的博客,下面是转载内容 C++虚基类详解 1、虚基类的作用从上面的介绍可知:如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多份同名成员。 在引用这些同名的成员时,必须在派生类对象名后增加直接基类名,以避免产生二义性,使其惟一地标识一个成员,如    

杜恒其的博客 1034

C++学习20 虚基类详解

多继承时很容易产生命名冲突,即使我们很小心地将所有类中的成员变量和成员函数都命名为不同的名字,命名冲突依然有可能发生,比如非常经典的菱形继承层次。如下图所示: 类A派生出类B和类C,类D继承自类B和类C,这个时候类A中的成员变量和成员函数继承到类D中变成了两份,一份来自 A-->B-->D 这一路,另一份来自 A-->C-->D 这一条路。 在一个派生类中...

dengaoxin0873的博客 321
上一篇: C++基础学习之派生
下一篇: HFSS使用小结
ithLiu
博客等级 码龄10年 26粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值