探索:C++继承中虚表与虚基表的内存存储

news2024/11/23 7:20:53
探讨:菱形虚拟继承的虚基表和虚表

在继承和多态里,总是能听到虚表、虚基表这样的词汇,没有洞悉其根本的人很容易将它们混淆,因此,我们对这两个“虚”“表”进行实践,来更好地理解它们。

通俗些说:
虚基表,即虚基类表,存放的是偏移量,是该表的位置与基类那一部分内容的地址之间的距离。
虚表:即虚函数表,存放的是函数指针,是某个类中所有虚函数的指针的集合。

  1. 初始&菱形虚拟继承

    有这么一段菱形虚拟继承的代码:

    class A 
    { 
    public: 
    	void func1() {
    		cout << "A::func1()" << endl;
    	} 
    	int a;
    }; 
    class B : virtual public A 
    { 
    public: 
    	int b;
    };
    class C : virtual public A
    {
    public:
    	int c;
    };
    class D : public B, public C
    {
    public:
    	int d;
    };
    
    int main()
    {
    	D d1;
    	d1.a = 1;
    	d1.b = 2;
    	d1.c = 3;
    	d1.d = 4;
    	return 0;
    }
    

    这是一个典型的菱形虚拟继承,我们通过调试,来看看它在内存中的布局:

    在这里插入图片描述

    因为没有虚函数,所以没有虚函数表(虚表)。
    而虚基类表(虚基表)来自于:菱形虚拟继承(虚拟:解决菱形继承的二义性和冗余)

  2. 重写/覆盖

    class A 
    { 
    public: 
    	virtual void func1() 
    	{
    		cout << "A::func1()" << endl;
    	} 
    	int a;
    }; 
    class B : virtual public A 
    { 
    public: 
    	void func1() 
    	{
    		cout << "B::func1()" << endl;
    	} 
    	int b;
    };
    class C : virtual public A
    {
    public:
    	int c;
    };
    class D : public B, public C
    {
    public:
    	int d;
    };
    
    int main()
    {
    	D d1;
    	d1.a = 1;
    	d1.b = 2;
    	d1.c = 3;
    	d1.d = 4;
    	return 0;
    }
    

    此时B中的func1()与A中的func1()构成重写(覆盖),整个过程请参看下面的调试过程:

    在这里插入图片描述

    刚才仅仅是在B中重写,那如果C中也进行重写呢?此时到底是重写B的实现,还是C的实现呢?
    答案是:都不是!
    如果B和C同时对A的func1()进行重写,编译器会报错,因为不明确!此时只需要在D中,也进行func1()的重写,那么就OK了!编译器会把D的实现重写进去,不会写B和C的实现。(当然B和C的重写并非没用,当有些场景创建“B b1;”B类型的对象b1时,就可以用到B的重写了)

  3. 中间两个派生类有自己的虚函数

    刚才的代码都是基类A的虚函数,如果派生类自己也有虚函数呢?请看:

    class A 
    { 
    public: 
    	virtual void func1() 
    	{
    		cout << "A::func1()" << endl;
    	} 
    	int a;
    }; 
    class B : virtual public A 
    { 
    public: 
    	void func1() 
    	{
    		cout << "B::func1()" << endl;
    	} 
        virtual void funcB()
        {
            cout << "B::funcB()" << endl;
        }
    	int b;
    };
    class C : virtual public A
    {
    public:
        void func1() 
    	{
    		cout << "C::func1()" << endl;
    	} 
        virtual void funcC()
        {
            cout << "C::funcC()" << endl;
        }
    	int c;
    };
    class D : public B, public C
    {
    public:
        void func1() 
    	{
    		cout << "D::func1()" << endl;
    	} 
    	int d;
    };
    
    int main()
    {
    	D d1;
    	d1.a = 1;
    	d1.b = 2;
    	d1.c = 3;
    	d1.d = 4;
    	return 0;
    }
    

    两个中间的派生类B和C,分别加上自己的虚函数funcB()funcC(),此时就没有刚才那么简单了,请看下图:

    在这里插入图片描述

    在原先的基础上,B和C分别多了一个虚函数表,存放它们自己的虚函数的地址。

  4. 最后一个派生类有自己的虚函数

    刚才是中间两个派生类有自己的虚函数,它们会产生自己的虚函数表,那么如果最后一个派生类(多继承的那个)也有自己的虚函数呢?你肯定以为它也会产生一个自己的虚函数表,但是你错了。请看下面的调试图:

    在这里插入图片描述

    至此可以窥得,C++多继承中的菱形继承,是多么的让人费解!也正因如此,我们不必要时,尽量避免写出菱形虚拟继承这样的结构出来,这对大家都好!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1513144.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

哪些行业实操会用到PMP的知识?

首先说项目管理适合那些行业。 项目管理覆盖的行业可以说非常广了&#xff0c;就我知道的&#xff0c;医疗啊&#xff0c;互联网啊&#xff0c;机械啊&#xff0c;建筑啊&#xff0c;金融啊&#xff0c;汽车啊&#xff0c;零售啊、广告啊等各行各业都是需要项目管理人员的。 …

H5简约星空旋转引导页源码

源码名称&#xff1a;H5简约星空旋转引导页 源码介绍&#xff1a;一款带有星空旋转背景特效的源码&#xff0c;带有四个按钮 需求环境&#xff1a;H5 下载地址&#xff1a; https://www.changyouzuhao.cn/11655.html

32x4点阵式LCD驱动芯片/抗干扰段码屏驱动/仪器仪表液晶驱动IC- VK1C21A/B SSOP48/LQFP48 COG

产品型号&#xff1a;VK1C21A/B 产品品牌&#xff1a;永嘉微电/VINKA 封装形式&#xff1a;SSOP48/LQFP48 可定制裸片&#xff1a;DICE(COB邦定片)&#xff1b;COG(邦定玻璃用) 工程服务&#xff0c;技术支持&#xff01; 概述&#xff1a; VK1C21A/B是一个点阵式存储映射…

一个简单的微信小程序表单提交样式模板

没什么东西&#xff0c;只是方便自己直接复制使用 .wxml <view class"box"><form bindsubmit"formSubmit"><view class"form-item"><text class"head">姓名&#xff1a;</text><input class"…

目标跟踪SORT算法原理浅析

SORT算法 Simple Online and Realtime Tracking(SORT)是一个非常简单、有效、实用的多目标跟踪算法。在SORT中&#xff0c;仅仅通过IOU来进行匹配虽然速度非常快&#xff0c;但是ID switch依然非常严重。 SORT最大特点是基于Faster RCNN的目标检测方法&#xff0c;并利用卡尔…

阿里又又发布了一个“AI神器”

阿里给“打工”朋友送上“节日礼物” 六一儿童节当天&#xff0c;阿里就给所有“打工”的大朋友送上了一份“节日礼物” 6月1日上午&#xff0c;阿里云发布了面向音视频内容的AI新品“通义听悟”&#xff0c;并正式公测 通义千问、通义听悟 这哥俩现在所处环境不同&#xff0…

Midjourney封禁Stability AI:恶意爬取数据,致服务器瘫痪24小时

这两家 AI 图像生成公司之间发生什么事了。虽然 AI 生图领域&#xff0c;看似百花齐放&#xff0c;但论资排辈&#xff0c;Midjourney、Stability AI 还是很受用户欢迎的。 Midjourney 把 Stability AI 拉入黑名单了&#xff0c;禁止后者所有员工使用其软件&#xff0c;直至另…

本地mysql5.7以上版本配置及my.ini

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 往期热门专栏回顾 专栏…

R语言系列4——R语言统计分析基础

目录 写在开头1. 描述性统计分析1.1 描述性统计分析的定义与重要性1.2 R语言中的描述性统计分析功能1.3 常用的描述性统计量及其在R中的计算方法1.4 使用R语言进行描述性统计分析的实际示例1.5 描述性统计分析的局限性和应用注意事项 2. 假设检验基础2.1. 假设检验的基本原理和…

自动驾驶---Motion Planning之构建SLT Driving Corridor

1 背景 在上篇博客《自动驾驶---Motion Planning之Speed Boundary》中,主要介绍了Apollo中Speed Boundary的一些内容,可以构造ST图得到边界信息,最后结合粗糙的速度曲线和路径曲线,即可使用优化的方法求解得到最终的轨迹信息(s,s,s,l,l,l)。 本篇博客笔者主要介绍近…

Qt中QCheckBox的三种状态设置

首先启用QCheckbox的tristate属性 //启用QCheckBox的tristate属性&#xff0c;使checkbox有三种状态。例&#xff1a; questionCheckBox->setTristate(true);//使用setCheckState(Qt::CheckState state)函数设置checkbox当前的状态。例&#xff1a; //Qt::CheckState是枚举…

探秘高校线上心理咨询室:Java+SpringBoot的实践

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

【vue video.js】The element or ID supplied is not valid. (videojs) element Ui

问题&#xff1a;使用video.js做了一个弹窗显示视频&#xff0c;效果如下 但是发现弹窗再次打开&#xff0c;视频播放失败&#xff0c;报错The element or ID supplied is not valid 原因是videojs找不到需要初始化的视频id&#xff0c;在关闭弹窗的时候需要重置video.js&…

C语言 指针(4) qsort函数

目录 前言 一、回调函数 二、qsort函数 2.1 使用qsort函数排序整型数据 2.2 使用qsort排序结构数据 三、qsort函数的模拟实现 总结 前言 今天我们主要来学习一下C语言中的qsort排序函数。 一、回调函数 回调函数就是⼀个通过函数指针调用的函数。 如果你把函数的指针&a…

148个Chatgpt关键词汇总-有爱AI实战教程(二)

演示站点&#xff1a; https://ai.uaai.cn 技能模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 导读&#xff1a;在使用 ChatGPT 时&#xff0c;当你给的指令越精确&#xff0c;它的回答会越到位&#xff0c;举例来说&#xff0c;假如你要请它帮忙写文案&#xff0c;如…

【公示】最新一批ITSS名单正式公布

小编从官方了解到&#xff0c;根据信息技术服务标准符合性评估相关规定&#xff0c;现对以下ITSS单位进行公示&#xff0c;公示期5个工作日。公示期内如有异议&#xff0c;请提供持有异议的正式书面文件&#xff0c;包括持有异议的原因及证据、单位或个人真实名称及有效联系方式…

c++函数SetConsoleTextAttribute

前言 正文 1.作用&#xff1a; 2.函数格式(重点)&#xff1a; 3.参数(重点)&#xff1a; 前言 实用(真的) 正文 1.作用&#xff1a; 更改cmd的背景色与字体颜色 2.函数格式(重点)&#xff1a; SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),10进制参数); …

BOOTMGR is missing 问题

同事一台win2k8的虚机在重启后无法引导开机&#xff0c;提示如下信息&#xff1a; 开始就觉得是引导分区设置错了。遂从网上下了一个winpe的镜像&#xff0c;装载到虚机“光驱”中&#xff0c;从光盘引导启动。打开“磁盘管理”后发现&#xff0c;果然&#xff0c;未安装系统…

大预言模型——ChatGPT,Claude3、Sora等技术

原文链接&#xff1a;大预言模型——ChatGPT&#xff0c;Claude3、Sora等技术https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247596849&idx3&sn111d68286f9752008bca95a5ec575bb3&chksmfa823ad6cdf5b3c0c446eceb5cf29cccc3161d746bdd9f26cc060f78c359e…

ubuntu:dpkg查看已经安装的软件包

dpkg -l 结果如下所示&#xff1a; 输出信息会很多&#xff0c;将结果导出到文件中&#xff1a; dpkg -l > my_file.txt