C++虚继承内存布局
C++菱形继承内存布局
编译器:Visual Studio 2019
关于如何查看内存布局
B
class B
{
public:B(): _ib(10), _cb('B'){cout << "B()" << endl;}B(int ib, char cb): _ib(ib), _cb(cb){cout << "B(int,char)" << endl;}virtualvoid f(){cout << "B::f()" << endl;}virtualvoid Bf(){cout << "B::Bf()" << endl;}
private:int _ib;char _cb;
};
B内存布局图:size = 12
虚函数指针(4B)
int型数据成员(4B)
char型数据成员(4B,3B用于对齐)
1>class B size(12):
1> +---
1> 0 | {vfptr}
1> 4 | _ib
1> 8 | _cb
1> | <alignment member> (size=3)
1> +---
1>B::$vftable@:
1> | &B_meta
1> | 0
1> 0 | &B::f
1> 1 | &B::Bf
1>B::f this adjustor: 0
1>B::Bf this adjustor: 0
B1
class B1
: virtual public B
{
public:B1(): _ib1(100), _cb1('1'){}B1(int ib, char ic, int ib1, char cb1): B(ib, ic), _ib1(ib1), _cb1(cb1){cout << "B1(int,char,int,char)" << endl;}virtualvoid f(){cout << "B1::f()" << endl;}virtualvoid f1(){cout << "B1::f1()" << endl;}virtualvoid Bf1(){cout << "B1::Bf1()" << endl;}
private:int _ib1;char _cb1;
};
B1内存布局图:size = 32
虚函数指针(4B)
虚基表指针(4B)
int型数据成员(4B)
char型数据成员(4B,3B用于对齐)
vtordisp(4B)
从基类B继承来的12B
1>class B1 size(32):
1> +---
1> 0 | {vfptr}
1> 4 | {vbptr}
1> 8 | _ib1
1>12 | _cb1
1> | <alignment member> (size=3)
1> +---
1>16 | (vtordisp for vbase B)
1> +--- (virtual base B)
1>20 | {vfptr}
1>24 | _ib
1>28 | _cb
1> | <alignment member> (size=3)
1> +---
1>B1::$vftable@B1@:
1> | &B1_meta
1> | 0
1> 0 | &B1::f1
1> 1 | &B1::Bf1
1>B1::$vbtable@:
1> 0 | -4
1> 1 | 16 (B1d(B1+4)B)
1>B1::$vftable@B@:
1> | -20
1> 0 | &(vtordisp) B1::f
1> 1 | &B::Bf
1>B1::f this adjustor: 20
1>B1::f1 this adjustor: 0
1>B1::Bf1 this adjustor: 0
1>vbi: class offset o.vbptr o.vbte fVtorDisp
1> B 20 4 4 1
B2
class B2: virtual public B
{
public:B2(): _ib2(1000), _cb2('2'){}B2(int ib, char ic, int ib2, char cb2): B(ib, ic), _ib2(ib2), _cb2(cb2){cout << "B2(int,char,int,char)" << endl;}virtualvoid f(){cout << "B2::f()" << endl;}virtualvoid f2(){cout << "B2::f2()" << endl;}virtualvoid Bf2(){cout << "B2::Bf2()" << endl;}
private:int _ib2;char _cb2;
};
B2内存布局图:size = 32
虚函数指针(4B)
虚基表指针(4B)
int型数据成员(4B)
char型数据成员(4B,3B用于对齐)
vtordisp(4B)
从基类B继承来的12B
1>class B2 size(32):
1> +---
1> 0 | {vfptr}
1> 4 | {vbptr}
1> 8 | _ib2
1>12 | _cb2
1> | <alignment member> (size=3)
1> +---
1>16 | (vtordisp for vbase B)
1> +--- (virtual base B)
1>20 | {vfptr}
1>24 | _ib
1>28 | _cb
1> | <alignment member> (size=3)
1> +---
1>B2::$vftable@B2@:
1> | &B2_meta
1> | 0
1> 0 | &B2::f2
1> 1 | &B2::Bf2
1>B2::$vbtable@:
1> 0 | -4
1> 1 | 16 (B2d(B2+4)B)
1>B2::$vftable@B@:
1> | -20
1> 0 | &(vtordisp) B2::f
1> 1 | &B::Bf
1>B2::f this adjustor: 20
1>B2::f2 this adjustor: 0
1>B2::Bf2 this adjustor: 0
1>vbi: class offset o.vbptr o.vbte fVtorDisp
1> B 20 4 4 1
D
class D: public B1, public B2
{
public:D(): _id(10000), _cd('3'){}D(int ib, char cb, int ib1, char cb1, int ib2, char cb2, int id, char cd): B1(ib, cb, ib1, cb1), B2(ib, cb, ib2, cb2), B(ib, cb), _id(id), _cd(cd){cout << "D(...)" << endl;}virtualvoid f(){cout << "D::f()" << endl;}virtualvoid f1(){cout << "D::f1()" << endl;}virtualvoid f2(){cout << "D::f2()" << endl;}virtualvoid Df(){cout << "D::Df()" << endl;}
private:int _id;char _cd;
};
D内存布局图:size = 56
从基类B1继承的16B
从基类B2继承的16B
int型数据成员(4B)
char型数据成员(4B,3B用于对齐)
vtordisp(4B)
从基类B继承的12B
虚基表指针存储的内容是什么?(以B2的vbptr为例,地址为20)
① 虚基表指针与子类对象首地址的偏移量(-4,子类B2首地址为16)
② 虚基表指针到虚基类部分的偏移量(24,虚基类B首地址为44)
多重继承:
① 每个基类都有自己的虚函数表:B1,B2
② 派生类如果有自己的虚函数,会被加入到第一个虚函数表中:D自己的虚函数Df被加入到B1的虚函数表中
③ 内存布局中,基类的布局按照被声明时的顺序排列:先B1后B2,如果反过来,内存布局会改变,D自己的虚函数会被加入到B2的虚函数表中(可自己实践)
④ 派生类会覆盖基类的虚函数,只有第一个虚函数表中存放的是真实的被覆盖的函数的地址,其它虚函数表中存放的并不是真实的地址,而是一条跳转指令
1>class D size(56):
1> +---
1> 0 | +--- (base class B1)
1> 0 | | {vfptr}
1> 4 | | {vbptr}
1> 8 | | _ib1
1>12 | | _cb1
1> | | <alignment member> (size=3)
1> | +---
1>16 | +--- (base class B2)
1>16 | | {vfptr}
1>20 | | {vbptr}
1>24 | | _ib2
1>28 | | _cb2
1> | | <alignment member> (size=3)
1> | +---
1>32 | _id
1>36 | _cd
1> | <alignment member> (size=3)
1> +---
1>40 | (vtordisp for vbase B)
1> +--- (virtual base B)
1>44 | {vfptr}
1>48 | _ib
1>52 | _cb
1> | <alignment member> (size=3)
1> +---
1>D::$vftable@B1@:
1> | &D_meta
1> | 0
1> 0 | &D::f1
1> 1 | &B1::Bf1
1> 2 | &D::Df //将D中的虚函数加在B1虚函数表中?
1>D::$vftable@B2@:
1> | -16
1> 0 | &D::f2
1> 1 | &B2::Bf2
1>D::$vbtable@B1@:
1> 0 | -4 //虚基表指针与子类对象首地址的偏移量
1> 1 | 40 (Dd(B1+4)B) //虚基表指针到虚基类部分的偏移量
1>D::$vbtable@B2@:
1> 0 | -4
1> 1 | 24 (Dd(B2+4)B)
1>D::$vftable@B@:
1> | -44
1> 0 | &(vtordisp) D::f
1> 1 | &B::Bf
1>D::f this adjustor: 44
1>D::f1 this adjustor: 0
1>D::f2 this adjustor: 16
1>D::Df this adjustor: 0
1>vbi: class offset o.vbptr o.vbte fVtorDisp
1> B 44 4 4 1
相关文章:
C++虚继承内存布局
C菱形继承内存布局 编译器:Visual Studio 2019 关于如何查看内存布局 B class B { public:B(): _ib(10), _cb(B){cout << "B()" << endl;}B(int ib, char cb): _ib(ib), _cb(cb){cout << "B(int,char)" << endl;}vi…...
IO模型--从BIO、NIO、AIO到内核select、poll、epoll剖析
IO基本概述 IO的分类 IO以不同的维度划分,可以被分为多种类型;从工作层面划分成磁盘IO(本地IO)和网络IO; 也从工作模式上划分:BIO、NIO、AIO;从工作性质上分为阻塞式IO与非阻塞式IO;…...
Zebec完成BNB Chain以及Near链上协议部署,多链化进程加速
从去年开始,Zebec 就开始以多链的形式来拓展自身的流支付生态,一方面向更多的区块链系统拓展自身流支付协议,即从Solana上向EVM链上对协议与通证等进行迁移与拓展。目前基本完成了在BNB Chain以及Near上的合约部署,且能够在这些EV…...
wpscan常见的使用方法
目录 简单介绍 暴力破解 信息收集 指定用户爆破 命令集合 简单介绍 Wordpress是一个以PHP和MySQL为平台的免费自由开源的博客软件和内容管理系统。 WPScan是Kali Linux默认自带的一款漏洞扫描工具,它采用Ruby编写,能够扫描WordPress网站中的多种安…...
Tree 底层源码实现(二叉树、递归、迭代)
树(Tree)是一种非线性数据结构,由一组节点和它们之间的边组成。在树中,每个节点都有零个或多个子节点,除了根节点外,每个节点都有且仅有一个父节点。树可以被用于许多应用程序,如文件系统、XML文…...
家政服务小程序实战教程13-接入客服
小程序在微信里使用,以其无需安装随用随走为特点。但是有个问题是,如果提供商品或者服务的,用户如果有问题往往希望平台的运营方给出专业的解答。为了满足这类需求,就需要我们提供客服接入的功能,用户可以点击客服图标…...
大白话高并发(三)
背景 高并发得第三篇,讲一讲压测吧,因为我的目的是模拟100万人同时来秒杀。 是不是真的要找100万个人 没必要 ,你就算100万人掐着表在同一毫秒内把请求请求某一台机器,服务器也不可能在同一时间处理那么多请求,因为…...
vue全家桶(四)前端工程化
vue全家桶(四)前端工程化1.模块化的相关规范1.1模块化概述1.2模块化的分类A.浏览器端的模块化B.服务器端的模块化C.ES6模块化1.2.1 Node.js中通过bable体验ES6模块化1.2.2 ES6模块化的基本语法1.2.2.1 默认导出与默认导入1.2.2.2 按需导出与按需导入1.2.…...
超螺旋滑模控制(STA)
超螺旋滑模控制(Super Twisting Algorithm, STA) 超螺旋滑模控制又称超扭滑模控制,可以说是二阶系统中最好用的滑模控制方法。 系统模型 对于二阶系统可以建立具有标准柯西形式的微分方程组 {x˙1x2x˙2fg⋅u\begin{cases} \dot x_1 x_2 \\ \dot x_2 f g \cdo…...
NX二次开发编译时dll自动数字签名及拷贝
前言 在UG5.0开始,所有基于UG二次开发的DLL都要“签名”后才能被客户端上正版的NX调用。 一、基于C# 开发签名 1、添加资源文件 (1)项目类库上右键–>属性–>资源–>添加资源右边小三角–>添加现有文件–>切换到UG安装目录下…...
教你如何搭建人事OA-薪资管理系统,demo可分享
1、简介1.1、案例简介本文将介绍,如何搭建人事OA-薪资管理。1.2、应用场景根据设置薪资基础及考勤和绩效的数据计算得到各个员工工资详情。2、设置方法2.1、表单搭建1)新建表单【工资表】,字段设置如下;名称类型名称类型人员资料分…...
ChIP-seq 分析:Mapped 数据可视化(4)
1. Mapped reads 现在我们有了 BAM 文件的索引,我们可以使用 idxstatsBam() 函数检索和绘制映射读取的数量。 mappedReads <- idxstatsBam("SR_Myc_Mel_rep1.bam")TotalMapped <- sum(mappedReads[, "mapped"])ggplot(mappedReads, aes(x…...
Jenkins 基于Kubernetes 弹性构建池
流程:创建Jenkins Agent;获取Jenkins Agent的参数;渲染yaml模板;调用K8s API在固定的NS中创建一个Pod;运行Jenkins pipeline到agent;创建Agentimport hudson.model.Node.Mode import hudson.slaves.* impor…...
经典算法题---链表奇偶重排(好题)双指针系列
我听别人说这世界上有一种鸟是没有脚的,它只能够一直的飞呀飞呀,飞累了就在风里面睡觉,这种鸟一辈子只能下地一次,那一次就是它死亡的时候。——《阿甘正传》这一文章讲解链表的奇偶排序问题,这是一道不难但是挺好的链…...
数据仓库实战
目录1、最佳实战1.1 表的分类1.2 ETL策略1.3 任务调度2、项目实战2.1 项目概述2.2 数据描述2.3 架构设计2.4 环境搭建2.5 项目开发1、最佳实战 1.1 表的分类 维度建模中表的类型:事实表和维度表 事实表又可以分为:事务事实表、周期快照事实表、累积快照…...
GPT系列:GPT, GPT-2, GPT-3精简总结 (模型结构+训练范式+实验)
😄 花一个小时快速跟着 人生导师-李沐 过了一遍GPT, GPT-2, GPT-3。下面精简地总结了GPT系列的模型结构训练范式实验。 文章目录1、GPT1.1、模型结构:1.2、范式:预训练 finetune1.3、实验部分:2、GPT-22.1、模型结构2.2、范式:预…...
ASE12N65SE-ASEMI高压MOS管ASE12N65SE
编辑-Z ASE12N65SE在ITO-220AB封装里的静态漏极源导通电阻(RDS(ON))为0.68Ω,是一款N沟道高压MOS管。ASE12N65SE的最大脉冲正向电流ISM为48A,零栅极电压漏极电流(IDSS)为10uA,其工作时耐温度范围为-55~150摄氏度。ASE…...
centos8防火墙命令配置(开放端口)
查看防火墙状态:(root用户)firewall-cmd –state启动防火墙:(root用户)systemctl start firewalld.service查看防火墙开放端口:(root用户) firewall-cmd --list-ports …...
Instagram营销教程_编程入门自学教程_菜鸟教程-免费教程分享
教程简介 Instagram营销初学者教程 - 从简单和简单的步骤学习Instagram营销从基本到高级概念,包括概述,业务战略,安装和注册,发布和参与,活动审查,微调内容,营销工具和应用程序,集成…...
HTTP Code含义
HTTP Code描述详细100继续100(继续)状态代码表示一个已收到请求,尚未被拒绝服务器。服务器打算在请求已完全收到并已采取行动。当请求包含 Expect 标头字段时100-continue expectation,100响应表示服务器希望接收请求有效负载主体…...
Elasticsearch:Security API 介绍
在我之前的文章 “Elasticsearch:运用 API 创建 roles 及 users” ,我展示了如何使用 Security API 来创建用户及角色来控制访问 Elasticsearch 中的索引。在今天的文章中,我将展示一个使用 Security API 来创建一个用户及角色来访问一个索引…...
springmvc考研交流平台 java ssm mysql
随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,考研交流平台当然也不能排除在外,从备考资料、课程学习的统计和分析,在过程中会产生大量的、各种各样的…...
2.15 vue3 day01 setup ref setup的参数 prop slot插槽 自定义事件通信
二、常用 Composition API 官方文档: 组合式 API 常见问答 | Vue.js 1.拉开序幕的setup 理解:Vue3.0中一个新的配置项,值为一个函数。 setup是所有Composition API(组合API)“ 表演的舞台 ”。 组件中所用到的:数据…...
CentOs7更新Yum源
1.安装wget yum install -y wget 2.备份配置文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak 3.下载国内yum源文件(centOs7,比如阿里) wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.al…...
【C/C++】VS2019下C++生成DLL并且成功调用(金针菇般细)
目录 一,生成动态链接库 二,使用动态链接库 一,生成动态链接库 1.打开VS2019,创建新项目,选择 动态链接库(DLL) 模板后进行下一步 2.输入项目名称,其它默认就行(可自行选择),点击创建 3 工程…...
如何重新安装安卓手机系统
下载并安装您设备的驱动程序和ADB工具。如果您已经拥有了它们,请跳过此步骤。没有就百度下载。 打开终端或命令提示符,并将其设置为包含ADB二进制文件的目录。 启动设备并将其连接到计算机上。 在终端或命令提示符中运行以下命令以确认设备是否连接成…...
ArcGIS API for JavaScript 4.15系列(7)——Dojo中的Ajax请求操作
1、前言 作为重要的前后端交互技术,Ajax被广泛应用于Web项目中。无论是jQuery时代的$.ajax还是Vue时代下的axios,它们都对Ajax做了良好的封装处理。而Dojo也不例外,开发者使用dojo/request模块可以轻松实现Ajax相关操作,下面开始…...
智慧校园电子班牌系统
智慧电子班牌区别于传统电子班牌,智慧校园电子班牌系统更加注重老师和学生的沟通交流和及时数据交互。学校为每个教室配置一台智能电子班牌,一般安装于教室门口,用来实时显示学校通知、班级通知,可设置集中分布式管理,…...
软考高项——第五章进度管理
范围管理进度管理总线索规划进度管理定义活动活动排序估算活动资源估算活动时间制定进度管理计划控制进度进度管理总线索 进度管理的总线索包括: 1)规划进度管理 2)定义活动 3)活动排序 4)估算活动资源 5)…...
基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【二】【整合springSecurity】
1、创建数据库 注意:mysql默认字符集为utf8,默认排序规则为utf8_general_ci。一般我们也会选择字符集为utf-8 MySQL在5.5.3之后增加了这个utf8mb4的编码,utf8mb4完全向下兼容utf8,为了节省空间,一般情况下使用utf8也就…...
网站建设和软件开发/品牌传播策略
R编程语言中有许多库用来创建图表,其中饼状图是以不同颜色的圆的切片表示的值,这些切片被标记,并且每个切片对应的数字也在图表中表示。在R中,我们将正数作为向量输入的pie()函数创建饼状图,附加参数用于控制标签&…...
小企业网站服务器/网站seo关键词优化排名
给Linux虚机扩充硬盘空间 ( by quqi99 ) 作者:张华 发表于:2013-06-15 版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 ( http://blog.csdn.net/quqi99 ) 基本情况:我用vi…...
网站优化有哪些/公司网站搭建
数据链路层(一)3.1 使用点对点信道的数据链路层3.1.1 数据链路层和帧数据发送模型数据链路层的信道类型数据链路层使用的信道主要有以下两种类型:点对点信道。这种信道使用一对一的点对点通信方式。广播信道。这种信道使用一对多的广播通信方式,因此过程…...
网站用的是什么语言/sem推广代运营
从eclipse中增加了maven2的插件之后,maven默认的本地库的路径是${user}/.m2/repository/下,一般windows用户的操作系统都安装在C盘,所以这个目录 下的jar包比较危险。我尝试从myeclipse->preferences->java->build path->classpa…...
网站建设需要多钱/360推广和百度推广哪个好
什么是Zookeeper Zookeeper是一个高性能,分布式的,开源分布式应用协调服务。它提供了简单原始的功能,分布式应用可以基于它实现更高级 的服务,比如同步,配置管理,集群管理,名空间。它被设计为易…...
使wordpress支持全局搜索/网络优化工程师招聘信息
一条mysql教程 存在该记录则更新,不存在则插入记录的sql INSERT table (auto_id, auto_name) values (1, ‘yourname) ON DUPLICATE KEY UPDATE auto_nameyourname ON DUPLICATE KEY UPDATE的使用 如果您指定了ON DUPLICATE KEY UPDATE,并且插入行后会导…...