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#中对象内存模型................. ...
随机推荐
- Beetl学习总结(2)——基本用法
2.1. 安装 如果使用maven,使用如下坐标 <dependency> <groupId>com.ibeetl</groupId> <artifactId ...
- 在全局对象(不是指针)的构造函数里不要对std集合做太多操作
写MaxvisionOnvif的时候,我用个宏把每个Command类注册到了CommandBuilder里面,通过全局对象初始化实现的,如下: void CommandBuilder::Registe ...
- Bitnami LNMP集成包安装简单总结
前言发送图文消息时间点,访问量大,请求并发多,业务web机处理不过来,新增加了2台web机应对.搞过Linux软件安装的都知道,各种库的依赖会把人搞崩溃,尤其是服务器不能访问外网的情况下,会非常的蛋疼 ...
- PHP array_diff_key()
定义和用法 array_diff_key() 函数返回一个数组,该数组包括了所有在被比较的数组中,但是不在任何其他参数数组中的键. 语法 array_diff_key(array1,array2,ar ...
- 快速傅立叶变换&HDU 1402
参考http://www.cnblogs.com/v-July-v/archive/2011/08/13/2214132.html <算导> 那么,更快速的多项式乘法就依赖于能否把一个系数 ...
- Android 开发 ContentProvider 获取歌曲列表和联系人的样例
ContentProvider(内容提供者)是Android中的四大组件之中的一个. 主要用于对外共享数据.也就是通过ContentProvider把应用中的数据共享给其它应用訪问.其它应用能够通过C ...
- gradle配置国内的镜像
gradle配置国内的镜像 学习了:http://blog.csdn.net/stdupanda/article/details/72724181 http://blog.csdn.net/lj402 ...
- linux c编程訪问数据库
源代码例如以下: #include <stdio.h> #include <stdlib.h> #include <mysql/mysql.h> int main( ...
- Apache server配置
Apacheserver在我们生活中非经常常使用 今天给大家将一下mac 下apache server的配置 这对程序来说是必备技能之中的一个,假设我们在公司开发都是用的公司的server 将自己的代 ...
- 安装 KB2844286 导致SharePoint 2010 XSLT web part 显示出现错误
上周末给Windows 打完补丁后,周一在通过From SharePoint的方式插入图片时,出现了如下错误: Unable to display this Web Part. To troubles ...