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#中对象内存模型................. ...
随机推荐
- selenium等待
简介 在selenium操作浏览器的过程中,每一次请求url,selenium都会等待页面加载完成以后, 才会将操作权限在交给我们的程序. 但是,由于ajax和各种JS代码的异步加载问题,当一个页面被 ...
- ansible plugins 列表
[action plugins] [cache plugins]jsonfilememcachedmemorymongodbpickleredisyaml [callback plugins]acti ...
- CI笔记
1.控制器 实现自己的控制器MY_Controller是在./application/core/MY_Controller.php中. 2.类库 添加自己的类是放在./application./lib ...
- [bzoj2743][HEOI2012]采花_树状数组
采花 bzoj-2743 HEOI-2012 题目大意:给定n朵花,每朵花有一个种类,m次询问:一段区间中至少出现两朵花的种类的个数. 注释:$1\le n,m\le10^6$. 想法:这个题超级像H ...
- mongodb之用户/认证/角色/权限管理
前言 用户权限管理很重要,只给需要的权限,防止应用系统漏洞导致脱库 认证和授权 Authentication 认证识别,解决我是谁 Authorization 操作授权,我能做什么 认证机制 MONG ...
- Oracle批量恢复drop操作删除的表、索引等对象
/**********************************************************************查询Drop操作删除的对象select * from re ...
- ant+jmeter 报告优化
环境基础:ant+jmeter+java +jmeter脚本 1.将 JMeter的extras目录中ant-jmeter-1.1.1.jar包拷贝至ant安装目录下的lib目录中 2.修改JMete ...
- 利用jquery将页面中所有目标为“#‘的链接改为其他URL
有一张页面草稿,开始时为了方便,里面差不多所有的<a>都指向了"#".现在要修改为另一个地址,难道要全部修改吗?用jquery 改改就好.代码如下: <scrip ...
- luogu2278 [HNOI2003]操作系统
题目大意 写一个程序来模拟操作系统的进程调度.假设该系统只有一个CPU,每一个进程的到达时间,执行时间和运行优先级都是已知的.其中运行优先级用自然数表示,数字越大,则优先级越高.如果一个进程到达的时候 ...
- Spark入门之DataFrame/DataSet
目录 Part I. Gentle Overview of Big Data and Spark Overview 1.基本架构 2.基本概念 3.例子(可跳过) Spark工具箱 1.Dataset ...