C++ 虚基类

C++中虚基类相关的知识点 目录 前言 虚基类的作用 虚基类的声明 虚基类的初识化 前言 在上一篇的文章中我们知道了, C++语言是知识多继承的,并且一个子类可以有多个父类子类,拥有所有父类的成员变量,子类会继承父类的所有成员函数,而且子类的对象也可以被父类的任意对象使用 虚基类的作用 如果一个类中有多个直接的基类,并且这些直接的基类又有有一个共同的基类,则在最低层的派生类中就会保留这个间接的共同基类数据成员的多份同名成员,在我们下次访问,这些同名成员的时候,必须在派生类的对象名后直接增加基类名,并唯一的标识一个 阅读详情

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

虚基类的特点:

       虚基类构造函数的参数必须由最新派生出来的类负责初始化(即使不是直接继承);
       虚基类的构造函数先于非虚基类的构造函数执行。

  1. /**//************************************************************************ 
  2. * 混合继承:多基类继承与多重继承 
  3. ************************************************************************/  
  4. #include <IOSTREAM.H>  
  5. //基类  
  6. class CBase  
  7. ...{  
  8. protected:  
  9.     int a;  
  10. public:  
  11.     CBase(int na)  
  12.     ...{  
  13.         a=na;  
  14.         cout<<"CBase constructor! ";  
  15.     }  
  16.   
  17.     ~CBase()...{cout<<"CBase deconstructor! ";}  
  18. };  
  19.   
  20. //派生类1(声明CBase为虚基类)  
  21. class CDerive1:virtual public CBase  
  22. ...{  
  23. public:  
  24.     CDerive1(int na):CBase(na)  
  25.     ...{  
  26.         cout<<"CDerive1 constructor! ";  
  27.     }  
  28.       
  29.     ~CDerive1()...{cout<<"CDerive1 deconstructor! ";}  
  30.   
  31.     int GetA()...{return a;}  
  32. };  
  33.   
  34. //派生类2(声明CBase为虚基类)  
  35. class CDerive2:virtual public CBase  
  36. ...{  
  37. public:  
  38.     CDerive2(int na):CBase(na)  
  39.     ...{  
  40.         cout<<"CDerive2 constructor! ";  
  41.     }  
  42.     ~CDerive2()...{cout<<"CDerive2 deconstructor! ";}  
  43.     int GetA()...{return a;}  
  44. };  
  45.   
  46. //子派生类  
  47. class CDerive12:public CDerive1,public CDerive2  
  48. ...{  
  49. public:  
  50.     CDerive12(int na1,int na2,int na3):CDerive1(na1),CDerive2(na2),CBase(na3)  
  51.     ...{  
  52.         cout<<"CDerive12 constructor! ";  
  53.     }  
  54.     ~CDerive12()...{cout<<"CDerive12 deconstructor! ";}  
  55. };  
  56. void main()  
  57. ...{  
  58.     CDerive12 obj(100,200,300);  
  59.     //得到从CDerive1继承的值  
  60.     cout<<" from CDerive1 : a = "<<obj.CDerive1::GetA();  
  61.     //得到从CDerive2继承的值  
  62.     cout<<" from CDerive2 : a = "<<obj.CDerive2::GetA()<<endl<<endl;  
  63. }  

 

1. 子派生类对象的值:

  
     从上例可以看出,在类CDerived12的构造函数初始化表中,调用了间接基类CBase的构造函数,这对于非虚基类是非法的,但对于虚基类则是合法且必要的。
  对于派生类CDerived1和CDerived2,不论是其内部实现,还是实例化的对象,基类CBase是否是它们的虚基类是没有影响的。受到影响的是它们的派生类CDerived12,因为它从两条路径都能到达CBase。
         
2. 运行结果:

    由此可知,其公共基类的构造函数只调用了一次,并且优先于非基类的构造函数调用;并且发现,子派生类的对象obj的成员变量的值只有一个,所以,当公共基类CBase被声明为虚基类后,虽然它成为CDerive1和CDerive2的公共基类,但子派生类CDerive12中也只有它的一个备份。可以仔细比较与例2的运行结果有什么不同。



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

相关推荐

浅谈c++虚基类内存布局

引入虚基类的原因是为了解决三层继承,爷爷类重复存在的问题。大概操作如下:普通继承:当通过子类对象给爷爷类成员变量赋值时会出现二义性。虚继承:子类中只有一个爷爷类避免了二义性。只有对虚基类的成员变量进行处理如赋值的时候,才会用到虚基类表–取其中的值用作偏移值,来进行虚基类成员变量首地址的定位运算。

qq_39884728的博客 1269

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

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

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

C++虚基类的实现机制:笔记

在《深度探索C++对象模型》里,有一个问题,也是去公司面试的时候那些技术人员常问的问题:在C++中,obj是一个类的对象,p是指向obj的指针,该类里面有个数据成员mem,请问obj.mem和p->mem在实现和效率上有什么不同。答案是:只有一种情况下才有重大差异,该情况必须满足以下3个条件:(1)、obj 是一个虚拟继承的派生类的对象(2)、mem是从虚拟基类派生下来的成员(3)、p是基类类型的

jiangnanyouzi的专栏 1万+

虚基类的基本概念

C++提供了**虚基类**使得在继承共同间接基类时只保留一份成员。

分享一些自己的学习心得体会和总结! 1万+

解密微信DAT图片:一键转换JPG/PNG/GIF的实用指南

本文详细解析微信DAT图片的加密机制及转换方法,提供从定位文件到使用WeijieSoft工具一键转换JPG/PNG/GIF的完整指南。涵盖新旧版微信存储路径差异、批量处理技巧及常见问题解决方案,帮助用户高效恢复重要图片并释放存储空间。

weixin_29305337的博客 3621

光耦选型避坑指南:如何根据CTR参数精准计算输入输出电阻(附24V工业场景实例)

本文深入解析光耦选型核心,聚焦电流传输比(CTR)参数及其衰减特性,提供从输出需求反向推导输入输出电阻的精准计算方法。文章以24V工业场景为例,结合光电耦合器数据手册,详细阐述了如何根据CTR最小值进行降额设计,并给出包含反接保护、TVS管等在内的完整保护电路方案,旨在构建高可靠、长寿命的信号隔离电路,避免因选型或设计不当导致的系统故障。

nept的博客 1040

C++中的“虚”

本博文整理的知识点是C++中有关虚的一切,包括:虚函数,纯虚函数,纯虚类(抽象类),虚基类,虚析构函数、虚基类、虚继承、虚函数表… 1.什么是虚函数,有什么作用? 前言 先理解多态:http://blog.youkuaiyun.com/BillCYJ/article/details/79523110,磨刀不误砍柴功。 若派生类内定义了一个与基类同名的成员函数(假设是非虚函数的成员函数),该现象称为...

陈云佳的专栏 1930

Zemax操作41--公差分析(一)

zemax公差

lzy750750的博客 5973

具体类、虚类、抽象类(纯虚类)、接口

具体类、虚类、抽象类(纯虚类)、接口 先明确 虚函数 和 纯虚函数 的概念 虚函数(impure virtual):也称为“虚方法”,在类中声明为 virtual 并实现了的成员函数。 纯虚函数(pure virtual):也称为“抽象函数”或“抽象方法”,一种特殊的虚函数,在类中没有给出该虚函数的实现,它的实现留给该基类的派生类去做。 具体类、虚类、抽象类(纯虚类)、接口 的定义: 具体类,即没有纯虚函数的类。 虚类,即含有虚函数但不含有纯虚函数的类。 抽象类,即含有纯虚函数和非虚函数的类

qianqian7759的博客 2299

C# chart以鼠标所在位置为中心进行缩放

以前都用labview做一些软件,但给出去总是会遇到版本,安装包过大等一些问题,于是想自学C#,记录一下使用过程中遇到的一些问题和解决措施,便于日后回顾。 在这个项目中需要绘制折线图,由于数据比较大,需要对图表进行缩放操作,以鼠标为中心对图表进行缩放,在网上查找了一些资料没找到我想要的,于是自己想了一个解决方案,可以基本实现,但略显繁琐,由于刚开始学习C#,对一些操作不太了解,若以后遇...

fei的博客 6363

FFmpeg实战:5分钟搞定m3u8视频下载与ts文件合并(附完整命令)

本文详细介绍了如何使用FFmpeg快速下载m3u8视频并合并ts文件为mp4格式。通过简洁的命令行操作,读者可以轻松完成视频处理任务,包括环境准备、链接获取、下载合并及性能优化等实用技巧,特别适合需要高效处理流媒体内容的用户。

weixin_30836759的博客 221

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

网神 SecGate 3600 防火墙 app_av_import_save文件上传漏洞(含批量验证poc)

网神 SecGate 3600 防火墙 app_av_import_save文件上传漏洞(含批量验证poc)

weixin_43567873的博客 298

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

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

小浣熊的博客 3万+

【Flink】FlinkSQL如何触发执行计算

Table (通过 StatementSet.addInsert() 输出给某个 Sink)和 INSERT 语句 (通过调用 StatementSet.addInsertSql())会先被缓存到 StatementSet 中,StatementSet.execute() 方法被调用时,所有的 sink 会被优化成一张有向无环图。该方法是用来将一个表的内容插入到目标表中,一旦该方法被调用, TABLE API 程序立即被翻译。该方法是用来执行一个 SQL 语句,一旦该方法被调用, SQL 语句立即被翻译。

一杯咖啡半杯糖的博客 1007

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【一天一篇CPP】C++的虚基类

一个派生类有多个直接基类,这些基类又有一个共同的基类,如图【画的很随便,就是B和C集成于A,Dji】

c熊 1107

visio安装包

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

C++的虚基类

/ 注意关键字virtualpublic:int b1 = 2;类B1就叫做从A虚继承,A在被虚继承的情况下被称为虚基类,注意,虚基类是有条件的,只有在被虚继承的时候才是虚基类。

b1049112625的博客 1455

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

【C++高级主题】虚基类的声明

C++ 引入了 虚基类(Virtual Base Class)机制。通过在继承时使用virtual关键字,让多个派生类共享同一个基类的实例,从而消除数据冗余和访问二义性。

byte轻骑兵的技术小窝 1924

C++虚基类的作用

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

caomiao2006的专栏 3万+

C++中的虚基类

C++中的虚基类的详解

一怀明月的博客 1322

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

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

u014472011的博客 957
上一篇: is-a与has-a的关系
ReverseThinking
博客等级 码龄14年 1粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值