C++当中的virtual继承

Effective C++ 条款36:绝不重新定义继承而来的 non-virtual 函数 深入解析 Effective C++ 条款36,理解为什么不应该重新定义继承而来的 non-virtual 函数,掌握静态绑定与动态绑定的本质区别,避免面向对象设计中的常见陷阱。 阅读详情
今天专门看了一下虚继承的东西,以前都没怎么用过,具体如下:
父类:  
class   CParent  
{  
....  
};  
继承类的声明比较特别:  
class   CChild   :   virtual   public   CParent  
{  
....  
}  
请问,这个"virtual"是什么作用及含义?  
---------------------------------------------------------------  

表示虚拟继承,和普通继承是C++的两种继承方式。  
例如B1、B2   继承A   而C多重继承B1、B2  
如果普通继承则C包含两份A的拷贝,分别来自于B1、B2  
而虚拟继承则只包含一份A的拷贝  
---------------------------------------------------------------  

这个"virtual"是什么作用及含义?  
证明这个CParent是CChild   的虚基类  
虚基类   的   作用  
虚基类是指:class   SubClass   :   virtual   public   BaseClass   中以virtual声明的基类!!由于C++支持多重继承,所以对于一个派生类中有几个直接父类,而几个直接父类中有几个可能分别继承自某一个基类(就是父类的父类),这样在构造最终派生类时,会出现最终派生类中含有多个同一个基类的情况,就会产生二义性的问题(不知道该调用哪个基类的成员变量和函数),为解决此问题,需要使用虚基类,即只对此基类生成一块内存区域,这样最终派生类中就只会含有一个基类了 
典型的需要用虚基类的情况如下:  
                        A  
                      /   \  
                    B       C  
                      \   /  
                        D  
其中D继承自BC,BC分别继承自A,所以A要分别被BC虚拟继承  
程序嘛…………  

class   A   {  
    public:  
        void   printA()   {cout<<"this   is   A\n";}  
};  
class   B:virtual   public   A;  
class   C:virtual   public   A;  
class   D:public   B,public   C;  

这样在D构造出来后,它的存储区域中只有一个A,不会有二义性问题  
比如:D   d=new   D;  
此时若使用d.printA();不会有问题;但若B和C不是虚继承自A,就会有二义性问题 
COM中 多重继承不采用虚拟继承, 否则会导致与COM不兼容的vtbl。若 IX 和 IY 按照虚拟继承方式继承IUnknown,那么 IX 和 IY 的vtbl中的头三个函数指向的将不是IUnknown的三个成员函数(详见Com技术内幕)
IUnknown        ->            IX                         
                                                    --->        CA 
IUnknown        ->            IY 
通常将一种类型的指针转换成另外一种类型的指针并不会改变指针的值,但为了支持多重继承,在某些情况下,C++必须改变类指针的值。COM中的多接口继承就是如此,此时 
CA* pA = new CA(); 
IY * pc = pA;                                  会被编译器改成   IY * pC = (char * )pA + deltaIY(一个偏移量);
基类的析构函数也应该定义成virtual才会在继承类的实例析构时被调用以清除基类用到的资源。
C++:46---绝不重新定义继承而来的non-virtual函数 一、看一个隐藏non-virtual函数的例子假设class D以public的方式继承于class B,代码如下:class B {public:void mf();};class D... 阅读详情

相关推荐

【机器人路径规划】基于改进型A*算法的机器人路径规划(Python代码实现)

本文针对传统A算法在机器人路径规划中存在的搜索效率低、路径不平滑等问题,提出了一种改进型A算法。该算法通过引入跳点搜索(JPS)技术优化子节点扩展方式,结合贝塞尔曲线或B样条曲线进行路径平滑处理,并采用动态启发式函数和自适应邻域搜索策略,显著提升了路径规划的效率和路径质量。实验结果表明,改进型A*算法在复杂环境下能有效减少搜索节点数量,缩短路径长度,提高路径平滑性,且具备动态避障能力。

2501_92867626的博客 1583

C++语法——详解虚继承

一.什么是虚继承所谓虚继承(virtual)就是子类中只有一份间接父类的数据。该技术用于解决多继承中的父类为非虚基类时出现的数据冗余问题,即菱形继承问题。,那么,当我们用D实例化对象调用a时,编译会报错,因为发生了混淆。除非指定类域B或C。当然指定A也可以,因为默认会从第一个父类中找。此时,D的实例化对象内部结构如下:而当我们使用虚继承时,结构是下图这样,D中只有一份父类A,当我们调用A中数据时,并不会发生冗余。

weixin_61857742的博客 3万+

Python验证码识别神器ddddocr:5分钟搞定网站登录自动化(附完整代码)

本文详细介绍了如何使用Python开源库ddddocr快速实现验证码识别,结合Selenium完成网站登录自动化。ddddocr作为轻量级OCR工具,支持多种验证码类型,识别速度快且准确率高,特别适合自动化测试和爬虫开发。文章包含完整代码示例,从环境配置到实战应用,帮助开发者5分钟内实现验证码破解。

sprite的博客 798

C++虚函数、虚继承:virtual

如果基类的虚函数,在派生类当中没有重新定义,那么还是会使用基类当中的该函数。

Dream_No_More的博客 1483

[QMT量化交易小白入门]-四十四、年化收益48%的策略要兼容回测和实盘,将实盘改为定时任务的方式

本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写100篇左右。QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。

木头大左的博客 1373

卫朋:IPD流程落地之产品开发验证阶段解读

IPD验证阶段

产品线负责人 1487

彻底弄懂C++虚拟继承

为了解决普通继承的“数据冗余”和“二义性”的问题,C++引入了虚拟继承使得在多重继承下,基类成员只继承一份。 这篇博客主要解析1.虚拟继承机制,如何做到的? 2.它和普通继承有什么区别?3.虚拟继承同时满足多态会怎样? .........

weixin_44212838的博客 1万+

Python控制Keysight DAQ973A/DAQ970A实现数据采集

本文介绍了如何通过编程实现Keysight DAQ973A数据采集系统的自动化温度测量。首先,通过GPIB线将PC与仪器连接,并使用热电耦测量线连接被测装置。接着,通过查阅Keysight官网提供的编程手册,获取了实现温度测量所需的SCPI指令。然后,使用pyvisa库编写代码,与仪器进行交互,发送SCPI指令并读取测量结果。代码中整合了配置和查询指令,并将测量结果转换为浮点数格式。最后,将整个流程封装为命令行工具,用户可以通过配置文件设置参数,并执行自动化测试,测试结果将保存为CSV文件。整个过程实现了温

xgh1951的博客 1887

C++中继承及virtual小结

一、继承基础知识C++中的继承1.1继承的基本概念类与类之间的关系has-A,包含关系,用以描述一个类由多个“部件类”构成,实现has-A关系用类的成员属性表示,即一个类的成员属性是另一个已经定义好的类。use-A,一个类使用另一个类,通过类之间的成员函数相互联系,定义友元或者通过传递参数的方式来实现。(和组合不同)is-A,即继承关系,关系具有传递性。继承的特点子类拥有父类的所有属性和方法(除了...

sinat_27652257的博客 8784

Python爬虫实战:使用最新技术爬取新华网新闻数据

在当今信息爆炸的时代,网络爬虫技术已经成为获取互联网数据的重要手段。作为国内权威新闻媒体,新华网每天发布大量高质量的新闻内容,这些数据对于舆情分析、市场研究、自然语言处理等领域具有重要价值。本文将详细介绍如何使用Python最新技术构建一个高效、稳定的新华网新闻爬虫系统。本文详细介绍了如何使用Python最新技术栈构建一个高效、稳定的新华网新闻爬虫系统。我们从基础爬虫开始,逐步添加了代理支持、用户代理轮换、请求延迟、重试机制、动态页面渲染、数据存储等高级功能,最终实现了一个生产可用的分布式爬虫系统。

2201_76125261的博客 1771

HQChart实战教程54:Renko砖形K线图实现详解

Renko图(砖形图)起源于日本,只关注价格变动而忽略时间和成交量因素: 2.2 算法说明 初始化:使用第一根K线的收盘价创建第一个砖块 变动检测:计算当前价格与最后一个砖块的差值 砖块生成: 当价格变动≥砖块大小时,生成新砖块 当价格变动不足时,更新当前砖块的高低价 方向判断:根据价格变动方向确定砖块颜色 三、完整实现代码 四、Renko图的高级应用 4.1 动态砖块大小调整 4.2 Renko交易策略 三砖反转策略:趋势跟踪策略:本文详细介绍了Renko图的实现原理和在HQChart中的应

QQ_778132974的博客 873

C++中,virtual函数被继承后如何实现

在上面的例子中,Base 类有一个 virtual 函数 show(),Derived 类继承自 Base 并重写了 show() 函数。当我们调用 basePtr->show() 时,实际上执行的是 Derived 类中的 show() 函数,这就是多态性的体现。这样做有两个好处:一是可以确保你确实重写了基类中的函数(如果基类中没有这个函数,编译器会报错),二是可以提高代码的可读性,让读者更容易理解你的意图。// 通过基类指针指向派生类对象。// 调用的是派生类中的 show() 函数。

slty_123的博客 469

人形机器人开源资源大盘点(四):硬件开源平台

开源人形机器人平台推动技术民主化 本期聚焦四大开源人形机器人平台:斯坦福的ToddlerBot以6000美元低成本实现30自由度运动,支持仿真到现实的零样本迁移;法国Reachy2被HuggingFace收购,融合开源AI与硬件,适配医疗、工业等场景;国内OriginMan基于ROS2全开源,集成大模型能力,支持深度改造;OAN框架则为经典NAO机器人注入开源活力,扩展交互功能。这些平台通过不同路径降低研发门槛,推动人形机器人技术走向开放共享的未来。

Studying…… 370

c++中继承多态virtual和override

C++中,继承和多态通常与虚函数(virtual)一起使用,以实现运行时多态性。virtual在上面的示例中,Base类中的print函数被声明为虚函数,而Derived类中重写了这个虚函数。当通过指向Derived对象的Base指针调用print函数时,会调用Derived类中的版本,实现了多态性。这是因为虚函数的调用在运行时动态绑定到正确的函数版本。

clayhell的博客 1086

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

C++ 多重继承 virtual public(虚继承类

c++的关键字虚基类,irtual关键字用于支持运行时多态性,它是实现动态绑定(dynamic binding)的关键。virtual关键字主要用于类的成员函数声明中,允许在派生类中重写(override)基类的函数,并确保通过基类的指针或引用来调用函数时,会调用到正确类型的对象所对应的函数版本。顺序可以改变,虚基类(Virtual Base Class) ,虚基类(Virtual Base Class)是C++中用于解决多重继承中“菱形继承”问题的一种机制。

hanwei020502的博客 903

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

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

cpp 钻石继承(不带virtual和带virtual)

cpp 钻石继承(不带virtual和带virtual)

weixin_45050132的博客 112

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

C++----菱形继承:virtual 与非 virtual 的区别

菱形继承(Diamond Inheritance)是指一个类同时从两个继承自同一个基类的类派生而来,形成菱形结构。A/ \B C\ /DA是基类B和C分别继承自AD同时继承自B和C这样会导致D 中有两份 A 子对象,从而出现二义性问题。继承方式A 子对象份数是否存在二义性构造函数调用规则非 virtual2 份有B、C 各自调用 A 的构造函数virtual1 份无必须由最派生类 D调用 A 的构造函数。

w_z_j 351

c++ 类继承加virtual和不加virtual有什么区别

特性普通继承 (虚继承 (基类子对象数量每条继承路径一个独立副本整个继承体系只有一个共享副本菱形继承是否安全不安全,导致二义性和数据冗余安全,消除二义性和冗余构造函数调用每个派生类都直接构造自己的基类只有最派生类构造虚基类,中间类不构造基类构造时机按继承顺序在派生类构造体之前在所有非虚基类之前,且仅一次内存布局基类子对象连续放在派生类之前有额外指针/偏移量,虚基类通常放在末尾访问基类成员效率直接偏移,效率高间接寻址,效率稍低适用场景单继承、无钻石问题的多重继承。

u014094704的博客 384

虚继承是什么意思_C++中virtual继承的深入理解

今天专门看了一下虚继承的东西,以前都没怎么用过,具体如下:父类:复制代码代码如下:class CParent{....};继承类的声明比较特别:class CChild : virtual public CParent{....}请问,这个"virtual"是什么作用及含义?--------------------------------------------------...

weixin_39762441的博客 531

C++基础(十八)多继承、菱形继承的解决方法、virtual关键字的使用

背景:c++允许多继承 注意:尽量避免多继承 继承会继承父类的所有属性(暂不考虑私有属性) 这样就会出现菱形继承的情况 即基类的属性 两个父类继承 最终子类拥有两个父类相同的基类属性 这样无法区分(可以利用作用域,但是还是出现了资源浪费的情况,和本不该出现两个相同的属性) 利用virtual关键字解决该问题 #include <iostream> using namespace std; class Animal { public: int m_Age; }; c...

we1less的博客 295

C++ 中不能被继承的类实现,及从中体现virtual 继承的一个特性

C++ view第一期中给出了如何实现一个不能被继承的类的方法。 如下: #ifdef NDEBUG#define FINAL_CLASS#else#define FINAL_CLASS : public virtual Private::NonDerivableHelper //这里的关键是virtual 只要是virtual就不能继承#endifnamespace Private{ c...

weixin_33753003的博客 91

【C++】类的继承(protected,virtual)

目录 类的继承 虚拟继承和虚拟函数 函数重写 父类指针指向子类对象 虚拟继承 继承:构造和析构 virtual析构函数 类的大小和virtual关键字的影响 多重继承 类的继承 类的继承的出现,是由于实际问题的需要。比如定义了一个男人类和女人类,这2个类之间有属性或者函数的重叠,那代码就有点冗余,所以为了解决这个问题,就将这些共有的属性和函数抽取出来,形成一个新类(比如这2类...

mjiansun的专栏 2648

C++的继承以及virtual的底层实现

1.还是举每次讲继承都会举得一个例子:老师和学生都有人类的共同信息----姓名,性别,身份证等等,而学生有学工号,课表。老师有上班时间等等,所以在类中就有了继承这一说,子类继承父类。2.基本形式就是:比如,你用proctected继承的话,你就不可以切片了,就相当于父类=子类,可以复制一下下面的代码就会发现问题所在了。

Qianxueban的博客 341

C++虚继承(virtual)

C++虚继承(virtual) 虚继承是为了解决同一个基类A被多个派生类(如B 、C)继承导致每个派生类中都保存有一份基类成员函数或者数据的副本,浪费了大量存储空间,也容易导致重命名的问题,还容易编译出错,如下所示 class a { protected: int ma; private: int mm; }; ---------------------------- class ...

GY-赵的博客 1155

CPP 继承,virtual(转)

fromhttps://www.cnblogs.com/embedded-linux/p/9613557.html?ivk_sa=1024320u CPP_封装_继承_多态 C++面向对象的三大特性:封装,继承,多态。 封装:使用一整套方法去创建一个新的类型,这叫类的封装。 继承:从一个现有的类型基础上,稍作改动,得到一个新的类型的方法,叫类的继承。 多态:当有几个不同的子类对象时,对象调用的函数会依据对象类型来调用相应类型的成员函数。 1. 继承 继承的主要目的是为了代码复用。 ..

maxzcl的博客 1308
上一篇: Hadoop 伪分布模式的安装
下一篇: Python高级编程技巧
张哲BJUT
博客等级 码龄15年 151粉丝 111原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值