Visual Studio查看虚函数表C++内存模型

news2024/11/17 21:21:44

在这里插入图片描述
在这里插入图片描述
在其他选项这里写上/d1 reportAllClassLayout,它可以看到所有相关类的内存布局,如果写上/d1 reportSingleClassLayoutXXX(XXX为类名),则只会打出指定类XXX的内存布局。近期的VS版本都支持这样配置。

运行程序的话就会自动生成一张虚函数表了:

#include <iostream>
using namespace std;

class Base {
public:
	int a = 0;
	int b = 0;
	virtual void f() { cout << "Base::f" << endl; }
	virtual void g() { cout << "Base::g" << endl; }
	virtual void h() { cout << "Base::h" << endl; }
};

class Derive : public Base {
	void g() { cout << "Derive::g" << endl; }
	virtual void g1() { cout << "Derive::g" << endl; }
};

int main()
{
	
	system("pause");
	return 0;
}

在这里插入图片描述

这个内存结构图分成了两个部分,上面是内存分布,下面是虚表。

单一继承(含成员变量+虚函数+虚函数覆盖)

在这里插入图片描述
通过代码查看的虚函数表是这样的:
在这里插入图片描述

多继承(含成员函数+虚函数+虚函数覆盖)

在这里插入图片描述
2个int型,一个short型(2字节padding后占4个字节),2个虚函数表,所以长度为5*4 = 20;虚函数表是这样的:
在这里插入图片描述
内存布局是这样:
在这里插入图片描述

深度为2的继承(成员变量+虚函数+虚函数覆盖)

在这里插入图片描述
3个int型,1个short型(2字节padding后占4个字节),2个虚函数表;代码显示的类的布局是这样:
在这里插入图片描述
内存布局:
在这里插入图片描述

class A {
public:
	virtual void f1() { cout << "A:f1" << endl; };
	virtual void f2() { cout << "A:f2" << endl; };
	virtual void f3() { cout << "A:f3" << endl; };
};

class B {
public:
	virtual void g1() { cout << "B:g1" << endl; };
	virtual void g2() { cout << "B:g2" << endl; };
	virtual void f2() { cout << "B:f2" << endl; };
};

class C :public A, public B {
	virtual void f1() { cout << "C:f1" << endl; };
	virtual void g1() { cout << "C:g1" << endl; };
};

class D :public C {
	virtual void f1() { cout << "D:f1" << endl; };
	virtual void g2() { cout << "D:g2" << endl; };
};

显示的内存分布是这样的:
在这里插入图片描述

重复继承(含成员变量+虚函数+虚函数覆盖)

在这里插入图片描述
在这里插入图片描述
由于基类中的m_nAge在内存分布中出现了两次,所以最后的结果是5个int类型和2个虚函数表,共计28字节。
在这里插入图片描述

单一虚继承(含成员变量+虚函数+虚函数覆盖)

在这里插入图片描述
所谓的虚继承就是把继承语法前加上virtual关键字,例如class B:virtual public A{…};
虚拟继承的出现就是为了解决重复继承中多个间接父类(可以解决菱形问题)的问题的 。内存分布是这样的:
在这里插入图片描述
这里需要解释下,因为出现了vfptr与vbptr,vfptr常见,但是vbptr却是第一次见,它指向CChildren的vbtable,另一个CChildren的vfptr位于0地址偏移处,它指向CChildren的vftable。从截图中也可以看出有2个vftable与1个vbtable(一共3个表)。vbtable中的8表示vbptr与基类的vfptr(这里即_vfptr::CParent)之间的偏移量(记录了基类vfptr的地址,即二重指针)。
在这里插入图片描述
另外提及一下,如果CChildren里全部是重载基类中的虚函数的话,或者说没有新的虚函数的话,_vfptr::CChildren指向的虚函数表就是空的,所以计算大小的时候可以不用算进去,因为实际上并没有创建相应的表格。
举个例子:

class A {
public:
	virtual void f1() { cout << "A:f1" << endl; };
	virtual void f2() { cout << "A:f2" << endl; };
	virtual void f3() { cout << "A:f3" << endl; };
};

class B:virtual A {
public:
	//virtual void g1() { cout << "B:g1" << endl; }; //如果打开注释,那么B就会有自己的vfptr
	void f2() { cout << "B:f2" << endl; };
	void f3() { cout << "B:f3" << endl; };
};

内存分布为:
在这里插入图片描述
即此时B类没有自己的vfptr。

多虚继承(含成员变量+虚函数+虚函数覆盖)

(1)CParent2是虚继承,CParent1是一般继承

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(2)CParent1是虚继承,CParent2是一般继承

在这里插入图片描述
在这里插入图片描述

(3)CParent1和CParent2都是虚继承

在这里插入图片描述
在这里插入图片描述
从这里可以看出vbtable确实是存储了指向相应的基类的vfptr的地址(二重指针)。

菱形的虚拟多重继承(含成员变量+虚函数+虚函数覆盖)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

Git:在实际开发中的使用(够你用十年)

Repository 我们先来认识一下版本库——Repository&#xff0c;接下来我们所有提到的 Git 基础命令&#xff0c;都是基于版本库的。 那么什么是版本库呢&#xff1f;版本库又名仓库&#xff0c;英文名 repository&#xff0c;你可以简单理解成一个目录&#xff0c;这个目录里面…

AcWing 数学知识

质数 模板&#xff1a; // 试除法判断质数 bool is_prime(int x) {if (x < 2) return false;//只需枚举一部分 使得 i< x / i, 时间复杂度为√nfor (int i 2; i < x / i; i )if (x % i 0)return false;return true; }// 试除法分解质因数 void divide(int n) {fo…

免费的 AI 动作捕捉工具 #Rokoko Video

创建动画可能很棘手&#xff0c;但使用对了技术和工具&#xff0c;可以轻松实现看起来很棒且功能流畅的完美动画。“ 为每个创作者配备动捕的力量。”近期&#xff0c;Rokoko 通过推出免费的 AI 动作捕捉工具 Rokoko Video来兑现这一承诺。图片来源 &#xff1a;Rokoko为什么说…

CSS弹性盒子(flexbox)实用指南

CSS弹性盒子&#xff08;flexbox&#xff09;实用指南上一节&#xff1a;《CSS 浮动 及其应用 》| 下一节&#xff1a;《CSS网格布局&#xff08;grid&#xff09;实用指南 》jcLee95&#xff1a;https://blog.csdn.net/qq_28550263?spm1001.2101.3001.5343 邮箱 &#xff1…

复习:矩阵计算与自动求导

矩阵计算 矩阵计算就是讲矩阵如何求导数&#xff0c;所有优化模型的求解也是通过求导数实现的。 首先回忆初高中学习的导数知识&#xff0c;这属于标量的导数。 将导数拓展到不可微的情况&#xff0c;这就是亚导数。 将导数拓展到向量&#xff0c;这就是梯度。 向量对向量求…

java优化-代码重,让代码更优美和简洁

简言 在项目工作中&#xff0c;经常会有优化&#xff0c;有sql优化&#xff0c;项目架构优化&#xff0c;业务层优化&#xff0c;代码结构优化等&#xff0c;这些优化都是为了系统&#xff0c;易维护&#xff0c;易懂&#xff0c;易扩展。下面是我个人总结的一些经验分享与大家…

JavaScript 函数-函数概念,使用,函数参数,返回值,arguments的使用,函数的申明方式...

JavaScript 函数 目录JavaScript 函数1. 函数的概念2. 函数的使用2.1 声明函数2.2 调用函数2.3 函数的封装3. 函数的参数3.1 形参和实参3.2 函数参数的传递过程3.3 函数形参和实参个数不匹配问题4. 函数的返回值4.1 return 语句4.2 return 终止函数4.3 return 的返回值4.4 函数…

喜讯 | 代谢组学领航企业百趣生物完成数千万元A+轮融资!

2023年1月3日&#xff0c;国内代谢组学研究领航企业上海百趣生物医学科技有限公司&#xff08;以下简称“百趣生物”&#xff09;宣布完成数千万元A轮战略融资。本轮融资由金域医学集团及其参股基金科金金域领投&#xff0c;老股东启明创投跟投。 本次融资资金将用于推动公司结…

教育行业课程介绍话术

教育行业&#xff0c;吸引生源是很重要的一项工作&#xff0c;但是机构或企业能吸引到生源的前提一定是学员对于机构所授课程有强烈的兴趣。 前言 教育行业&#xff0c;吸引生源是很重要的一项工作&#xff0c;但是机构或企业能吸引到生源的前提一定是学员对于机构所授课程有强…

MyBatisPlus ---- 插件

MyBatisPlus ---- 插件1. 分页插件a>添加配置类b>测试2. xml自定义分页a>UserMapper中定义接口方法b>UserMapper.xml中编写SQLc>配置文件d>测试3. 乐观锁a>场景b>乐观锁与悲观锁c>模拟修改冲突d>乐观锁实现流程e>MyBatis-Plus实现乐观锁1. 分…

蓝牙耳机什么牌子性价比高?性价比最好的蓝牙耳机排行

近年来&#xff0c;蓝牙耳机越来越成为人们日常生活中常见的数码产品之一&#xff0c;逐渐地&#xff0c;看到更多的音频厂商、手机厂商加入蓝牙耳机市场中来。最近&#xff0c;看到很多人问&#xff0c;蓝牙耳机什么牌子性价比高&#xff1f;下面&#xff0c;我来给大家分享一…

浅谈map和unordered_map的应用场景

map和unordered_map的适用场景 底层结构介绍 map底层是红黑树结构unordered_map底层是哈希结构; Hash适用场景(unordered_map) 内存存角度来说hash因为底层维护了哈希表的存在&#xff0c;内存消耗远大于红黑树&#xff0c;但是因为哈希表增删查改时的直接映射&#xff0c…

OpenFeign服务接口调用

✨ OpenFeign服务接口调用OpenFeign & FeignFeign基本介绍OpenFeign基本介绍二者对比OpenFeign的使用新建Module&#xff1a;cloud-consumer-feign-order80pom依赖application.yml全局配置文件主启动类Service1. 业务逻辑接口FeignClient配置调用provider服务2. 新建Paymen…

第三十九讲:神州无线AC基础管理配置

瘦AP零配置上线&#xff0c;对AP的管理和配置都在AC上进行。AC的基础管理包括AC的无线地址指定及无线功能开启、AP的注册、AP用户数管理、自动信道调整等。 一、配置AC无线IP地址 设置静态的无线IP地址查看AC选取的无线IP地址3.开启无线功能 二、AP注册 1&#xff0e;二层模式…

【网络结构设计】11、E-LAN | 通过梯度传输路径来设计网络结构

文章目录一、背景二、方法2.1 网络设计策略2.2 Partial Residual Networks2.3 Cross Stage Partial Networks2.4 Efficient Layer Aggregation Network三、效果论文&#xff1a;Designing Network Design Strategies Through Gradient Path Analysis 代码&#xff1a;暂无 出…

微服务应用视角解读如何选择 K8s 的弹性策略

头&#xff1a;潘俊峰 前言 微服务架构的出现&#xff0c;拆分了庞大的单体应用&#xff0c;让业务之间的开发与协作变得更加灵活。当面临业务流量增加的场景时&#xff0c;往往需要对一些应用组件进行扩容。K8s 在应用层面提供了 HPA&#xff0c;围绕 HPA 开源社区延伸出了 …

SAP-FI模块 处理自动生成会计凭证增强

FICO-模块一. 相关问题概览1. 固定资产业务过渡科目摘要增强功能-F-022. 固定资产业务过渡科目摘要增强功能-MIGO3. 主营业务收入等科目自动反记账功能二. 问题图片描述1. 固定资产业务过渡科目摘要增强功能-F-022. 固定资产业务过渡科目摘要增强功能-MIGO3. 主营业务收入等科目…

JavaScript 作用域-作用域概述,变量作用域,作用域链

JavaScript 作用域-作用域概述&#xff0c;变量作用域&#xff0c;作用域链 目录JavaScript 作用域-作用域概述&#xff0c;变量作用域&#xff0c;作用域链1. 作用域1.1 作用域概述1.2 全局作用域1.3 局部作用域 (函数作用域)1.4 JS 没有块级作用域2. 变量的作用域2.1 变量作用…

校验和之概念、计算原理、检验原理、实例计算、代码编程,力荐力荐力荐

阅读前请看一下&#xff1a;我是一个热衷于记录的人&#xff0c;每次写博客会反复研读&#xff0c;尽量不断提升博客质量。文章设置为仅粉丝可见&#xff0c;是因为写博客确实花了不少精力。不用担心你关注我而我却不关注你&#xff0c;因为我是个诚信互关的人&#xff01;&…

如何用LightningChart创建Android图表数据可视化应用程序?(下)

LightningChart JS 是一款高性能的 JavaScript 图表工具&#xff0c;专注于性能密集型、实时可视化图表解决方案。 LightningChart .JS | 下载试用&#xff08;qun&#xff1a;740060302&#xff09;https://www.evget.com/product/4189/download 在上一篇&#xff0c;我们介…