1、C++对象的内存分布和虚函数表:

C++对象的内存分布和虚函数表注意,对象中保存的是虚函数表指针,而不是虚函数表,虚函数表在编译阶段就已经生成,同类的不同对象中的虚函数指针指向同一个虚函数表,不同类对象的虚函数指针指向不同虚函数表。
2、何时进行动态绑定:
(1)每个类对象在被构造时不用去关心是否有其他类从自己派生,也不需要关心自己是否从其他类派生,只要按照一个统一的流程:在自身的构造函数执行之前把自己所属类(即当前构造函数所属的类)的虚函数表的地址绑定到当前对象上(一般是保存在对象内存空间中的前4个字节)。因为对象的构造是从最基类部分(比如A<-B<-C,A是最基类,C是最派生类)开始构造,一层一层往外构造中间类(B),最后构造的是最派生类(C),所以最终对象上绑定的就自然而然就是最派生类的虚函数表。
(2)析构函数的调用跟构造函数的调用顺序是相反的,它从最派生类的析构函数开始的。也就是说当基类的析构函数执行时,派生类的析构函数已经执行过,派生类中的成员数据被认为已经无效(包括派生类对象中的虚表指针)。假设基类中虚函数调用能调用得到派生类的虚函数,那么派生类的虚函数将访问一些已经“无效”的数据,所带来的问题和访问一些未初始化的数据一样。而同样,我们可以认为在析构的过程中,虚函数表也是在不断变化的,不断解绑定。
因此,在基类构造函数或者析构函数中调用虚函数,并不会绑定到派生类的实现上,因为在这两个函数执行时虚函数表指针指向的是基类的虚函数表。
3、C++中类的大小:
由 1 可知,C++对象中只保存非静态数据成员,成员函数和静态数据成员是存储在静态数据区的。
字节对齐(默认):
1、VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。
2、VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。
3、如果对齐字节数(#pragma pack(n)),那么
(1)各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数和n的较小值的倍数。
(2)结构的大小为结构中占用最大空间的类型所占用的字节数和n的较小值的倍数。
class A {
double d;
static int i;
void f() { std::cout << "A::f" << std::endl; }
}; // 8 byte,只有double数据成员占8字节,成员函数和静态数据成员不在对象中,而是在静态数据区
class B {
int i; //4
double j;//8
char k; //
}; // 24 byte,考虑字节对齐, 4 + 4 + 8 + 1 + 7, 蓝色的4是为了满足条件1,黑色的7是为了满足条件2。如果指定4字节对齐,4 + 8 + 1 + 3
class C {
virtual void f() { std::cout << "C::f" << std::endl; }
}; // 4 byte,虚函数表指针占4个字节
class D {
};// 1 byte,没有成员变量的结构或类的大小为1,因为必须保证结构或类的每一 个实例在内存中都有唯一的地址
注:
1、如果有成员对象,直接把成员对象展开到外部对象中,然后按照字节对齐的规律求大小。
2、虚继承的内存分布为:虚类指针-》派生类成员数据-》基类成员数据。其对齐方案是:首先把派生类所有成员当成一个嵌套结构体形式,位于最下面的基类的数据成员要保证自己对齐(首地址整除自己的字节数),但是不用在最下面添加字节保证整体是边界长度的整数倍(因为基类成员共享,不能把派生类当成一个整体)。
3、如果对象中有数组,可以把数组展开到对象中,然后按照字节对齐的规律求大小。
4、为什么要进行字节对齐
计算机组成原理教导我们这样有助于加快计算机的取数速度,否则就得多花指令周期了。为此,编译器默认会对结构体进行处理(实际上其它地方的数据变量也是如此),让宽度为2的基本数据类型(short等)都位于能被2整除的地址上,让宽度为4的基本数据类型(int等)都位于能被4整除的地址上,以此类推。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。
备注:visual studio 2010是按照默认方式进行字节对齐的 32位gcc按照4字节最齐
以上就是小编为大家带来的C++对象内存分布详解(包括字节对齐和虚函数表)全部内容了,希望大家多多支持~
# C++对象内存分布
# C++虚函数及虚函数表简析
# 详解C++虚函数表存储位置
# C++虚函数表实例分析
# C++实现打印虚函数表的地址
# C++虚函数表与类的内存分布深入分析理解
# C++ 中的虚函数表及虚函数执行原理详解
# C++虚函数表和虚析构介绍
# c++虚函数与虚函数表原理
# C++虚函数表深入研究
# c++虚函数表的实现原理
# 派生类
# 的是
# 绑定
# 象中
# 是在
# 放在
# 是从
# 较小
# 相对于
# 为该
# 自己的
# 类中
# 是为了
# 也不
# 都有
# 偏移量
# 在这
# 还会
# 中有
# 两次
相关文章:
宝塔面板创建网站无法访问?如何快速排查修复?
建站主机选择指南:服务器配置与SEO优化实战技巧
相册网站制作软件,图片上的网址怎么复制?
如何通过IIS搭建网站并配置访问权限?
建站之星24小时客服电话如何获取?
矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?
如何用西部建站助手快速创建专业网站?
如何通过二级域名建站提升品牌影响力?
如何在Golang中使用encoding/gob序列化对象_存储和传输数据
h5在线制作网站电脑版下载,h5网页制作软件?
网站制作公司排行榜,抖音怎样做个人官方网站
建站主机与虚拟主机有何区别?如何选择最优方案?
如何打造高效商业网站?建站目的决定转化率
自助网站制作软件,个人如何自助建网站?
上海网站制作网站建设公司,建筑电工证网上查询系统入口?
深圳企业网站制作设计,在深圳如何网上全流程注册公司?
建站主机SSH密钥生成步骤及常见问题解答?
临沂网站制作企业,临沂第三中学官方网站?
如何在阿里云购买域名并搭建网站?
如何通过虚拟机搭建网站?详细步骤解析
如何获取PHP WAP自助建站系统源码?
如何用景安虚拟主机手机版绑定域名建站?
学校建站服务器如何选型才能满足性能需求?
如何选择高效稳定的ISP建站解决方案?
义乌企业网站制作公司,请问义乌比较好的批发小商品的网站是什么?
制作网站怎么制作,*游戏网站怎么搭建?
IOS倒计时设置UIButton标题title的抖动问题
广州网站设计制作一条龙,广州巨网网络科技有限公司是干什么的?
Android滚轮选择时间控件使用详解
Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解
北京网站制作的公司有哪些,北京白云观官方网站?
装修招标网站设计制作流程,装修招标流程?
如何通过PHP快速构建高效问答网站功能?
c++23 std::expected怎么用 c++优雅处理函数错误返回【详解】
制作宣传网站的软件,小红书可以宣传网站吗?
C++时间戳转换成日期时间的步骤和示例代码
上海网站制作开发公司,上海买房比较好的网站有哪些?
建站之星代理如何优化在线客服效率?
C#如何使用XPathNavigator高效查询XML
网站制作需要会哪些技术,建立一个网站要花费多少?
导航网站建站方案与优化指南:一站式高效搭建技巧解析
如何快速搭建FTP站点实现文件共享?
如何用虚拟主机快速搭建网站?详细步骤解析
如何快速上传建站程序避免常见错误?
html制作网站的步骤有哪些,iapp如何添加网页?
电商平台网站制作流程,电商网站如何制作?
关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)
韩国服务器如何优化跨境访问实现高效连接?
如何快速生成可下载的建站源码工具?
深入理解Android中的xmlns:tools属性
*请认真填写需求信息,我们会在24小时内与您取得联系。