C++对象的内存模型
1. 普通对象模型
对象是如何在内存中布局的?
| 成员 | 存放位置 | 访问范围 |
|---|---|---|
| 非静态数据成员 | 每一个对象体内 | 为该对象专有 |
| 静态数据成员 | 程序的静态存储区内,只有一份实体 | 为该类所有对象共享 |
| 成员函数(静态/非静态) | 程序的代码段中,只有一份实体 | 为该类所有对象共享 |
| 类类嵌套的各种类型(typedef、class、struct、enum等) | 与放在类外面定义的类型除了定义域之外没有本质区别 | 遵循类内部的访问规则 |
因此,构成对象本身的只有数据,类的成员函数不属于任何一个对象。非静态成员函数与对象之间的关系是通过this指针绑定的。
2. 增加继承和虚函数的类的对象模型
派生类的对象是如何在内存中布局的?
| 成员 | 规则 |
|---|---|
| 继承自基类的非静态数据成员 | 作为对象自己专用的数据 |
| 继承自基类的非静态成员函数 | 作为类的成员函数一样访问 |
| 虚函数(继承的或者新增的) | 所有虚函数的地址都存放在vtable里 |
| 多态类每一个对象中的vptr | 函数指针的指针,指向所属类的vtable |
| 继承自基类的vptr | 继承和重用该vptr |
| 多重继承的多个分支 | 每个分支都继承一个vptr并生成一个对应的vtable |
vptr在派生类对象中的相对位置不会随着继承的层次改变而改变,一般编译器会将vptr放在所有数据成员的最前面。
为了支持RTTI,编译器会为每一个多态类创建一个type_info对象,并把其地址保存在该类vtable中的第一个位置。
3. vtable中虚函数指针的排列顺序
- 如果虚函数是第一次出现,则把它的函数地址指针依次插入到vtable的尾部。
- 如果派生类改写了基类的虚函数,则这个函数的地址在派生类vtable中的位置与其在基类vtable中的位置一直,而与其在派生类中的声明位置无关。也就是说一旦虚函数指针在vtable的位置确定,则它的位置就不会因为继承层次的改变而改变。
- 派生类没有改写的基类虚函数被继承,位置与原先在vtable中的位置相同。
C++对象的内存模型的更多相关文章
- Java对象的内存模型(一)
前言 新人一枚,刚刚入门编程不久,各方面都在学习当中,博文有什么错误的地方,希望我们可以多多交流! 最近,在开发App后台过程中,需要将项目部署到云服务器上.而云服务器的内存大小却只有1G.要如何做到 ...
- C++学习笔记----2.4 C++对象的内存模型
转载自:http://c.biancheng.NET/cpp/biancheng/view/2995.html点击打开链接 当对象被创建时,编译器会为每个对象分配内存空间,包括成员变量和成员函数. 直 ...
- 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响
首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack(n) ...
- 对C++对象内存模型造成的影响(类/对象的大小)
首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack(n) ...
- String的内存模型,为什么String被设计成不可变的
String是Java中最常用的类,是不可变的(Immutable), 那么String是如何实现Immutable呢,String为什么要设计成不可变呢? 前言 关于String,收集一波基础,来源 ...
- C++对象的内存分布和虚函数表
c++中一个类中无非有四种成员:静态数据成员和非静态数据成员,静态函数和非静态函数. 1.非静态数据成员被放在每一个对象体内作为对象专有的数据成员. 2.静态数据成员被提取出来放在程序的静态数据 ...
- Java对象的内存(一)
前言 新人一枚,刚刚入门编程不久,各方面都在学习当中,博文有什么错误的地方,希望我们可以多多交流! 最近,在开发App后台过程中,需要将项目部署到云服务器上.而云服务器的内存大小却只有1G.要如何做到 ...
- (转)JavaScript内存模型
JavaScript对象内存模型 转自:http://blog.csdn.net/u010425776/article/details/53617292 推荐-JavaScript作用域链内存模型: ...
- C++/C#中堆栈、对象内存模型、深浅拷贝、Array.Clone方法
转载自:http://blog.csdn.net/jarvischu/article/details/6425534 目录 1. C++/C#中对象内存模型................. ...
随机推荐
- hdu2017 字符串统计【C++】
字符串统计 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- CVE-2014-6271 漏洞告警
原理:BASH除了可以将shell变量导出为环境变量,还可以将shell函数导出为环境变量!当前版本的bash通过以函数名作为环境变量名,以“(){”开头的字串作为环境变量的值来将函数定义导出为环境变 ...
- 【Codeforces 478C】Table Decorations
[链接] 我是链接,点我呀:) [题意] 给你r,g,b三种颜色的气球 每张桌子要放3个气球 但是3个气球的颜色不能全都一样 (允许两个一样,或者全都不一样) 问你最多能装饰多少张桌子 [题解] 先把 ...
- 【[Offer收割]编程练习赛 14 A】小Hi和小Ho的礼物
[题目链接]:http://hihocoder.com/problemset/problem/1505 [题意] [题解] 考虑Meet in the middle. 因为两个数的和不是很大; 直接用 ...
- 【codeforces 796C】Bank Hacking
[题目链接]:http://codeforces.com/contest/796/problem/C [题意] 给你n个节点,你一开始选择一个节点,然后打掉它,然后与被打掉过的节点相连的节点才能被 打 ...
- [bzoj1935][Shoi2007]Tree 园丁的烦恼 _树状数组
Tree 园丁的烦恼 bzoj-1935 Shoi-2007 题目大意:给定平面上的$n$个点,$m$次查询矩形点个数. 注释:$1\le n,m\le 5\cdot 10^5$. 想法:静态二维数点 ...
- u-boot-2014.04移植FL2440(使用eclipse编辑uboot)
1.首先安装eclipse 安装指令 : apt-get install eclipse 使用上面的命令会安装好jdk 和eclipse,eclipse必须在Java环境执行,所以须要安装jdk环境. ...
- [C++基础]goto的用法
原文: http://blog.csdn.net/shimazhuge/article/details/8448773 ---------------------------------------- ...
- java代理使用 apache ant实现文件压缩/解压缩
[背景] 近日在研究web邮件下载功能,下载的邮件能够导入foxmail邮件client.可是批量下载邮件还需将邮件打成一个压缩包. 从网上搜索通过java实现文件压缩.解压缩有非常多现成的样例. [ ...
- 《Google 软件测试之道》摘录
最近刚刚看完<Google 软件测试之道>,受益颇多,遂记录下: 只有在软件产品变得重要的时候质量才显得重要 第一章:谷歌软件测试介绍 角色介绍 SWE(Software Engineer ...