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 在一个成员初始化列表中同时出现对虚基类和非虚基类构造函数的调用时,虚基类的构造函数先于非虚基类的构造函数的调用。


ORB-SLAM3的Euroc数据集测试 (一)测试运行 不同模式测试过程(以MH_03为例) 1、pure mono 运行SLAM: cd ORB-SLAM3/Example #run slam ./Monocular/mono_euroc ../Vocabulary/ORBvoc.txt ./Monocular/EuRoC.yaml "$pathDatasetEuroc"/MH03 ./Monocular/EuRoC_TimeStamps/MH03.txt dataset-MH03_mono 利用ORB-SLAM3自带.. 阅读详情

相关推荐

Vc出现不能连接到一个或多个 vCenter server 系统:http://vcenter-vx.utibet.edu.cn:443/sdk

问题描述: 解决办法: esxi6.7的bug 第一种通过升级系统来解决问题 第二种是通过删除数据来解决 第一步:进入到esxi的shell 第二步查看其中的服务开启状态 第二步 df -h 第三步 /opt/vmware/vpostgres/current/bin/psql -d VCDB -U postgres 第四步 SELECT nspname || '.' || relname AS "relation", pg_size_pretty(pg_total_relation_size(C.oi

m0_49328536的博客 9899

C++ 虚基类

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

我是小白呀的博客 1万+

RSA 2048/4096 签名校验算法

RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。 RSA是目前最有影响力和最常用的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。 今天只有短的RSA钥匙才可能被强力方式解破。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能...

qq_38769551的博客 9496

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万+

ACM论文LaTeX模板解析(三)| 文章顶部信息(Top matter))Part 1

文章顶部信息(Top matter))Part 1,文章类型、作者信息等

FreshManInC的博客 4853

FMEA-MSR步骤三:功能分析

目的 FMEA-MSR功能分析的主要目标: ● 功能及各功能之间的关系的可视化 ● 功能树/网络或等效功能矩阵参数图(P图) ● 顾客(外部和内部)功能与相关要求的关联 ● 要求或特性与功能的关联 ● 工程团队(系统、安全和组件)之间的协作 ● 失效分析步骤的基础 (点击链接进入官网领取软件试用) 在监视及系统响应的补充FMEA中,对失效探测和失效响应的监视视为其具有的功能。硬件和软件功能可能包括监视控制状态的功能。 故障/失效的监视和探测功能可能包括超出范围的探测、循环冗余校验、真实性检查和序列计数器检查

Infomass的博客 2389

C++虚基类详解

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

Gxy_w的博客 1573

CentOS 7 常用命令大全

CentOS中Linux命令

m0_63075763的博客 2018

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

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

2401_84976016的博客 418

Verilog的综合指令

Synopsys综合指令

烟花一时的博客 5445

Winform从入门到精通(21)——ProgressBar(史上最全)

本介绍ProgressBar控件的详细用法,包含所有属性、事件,绝对史上最全!

qq_34059233的博客 3350

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

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

GuangCZ的博客 227

R 语言 ggplot2 绘制精美高级全球地图

在本教程中,我们将学习如何使用R语言和ggplot2包绘制精美高级地图。ggplot2是一个功能强大的数据可视化包,它可以让我们创建漂亮、交互式的地图。我们将使用R中的一些其他包来处理地理空间数据,以便与ggplot2无缝协作。

Mrrunsen的博客 1866

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

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

cangersuifeng的博客 152

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

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

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

绿皮哥布林 564

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

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

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

小浣熊的博客 3万+

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

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的博客 5106

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、付费专栏及课程。

余额充值