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#中对象内存模型................. ...
随机推荐
- BZOJ 4278 [ONTAK2015]Tasowanie (后缀数组)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4278 题解: 居然把后缀数组写成n^2的..我真厉害.. 想了无数种方法,最后发现就是 ...
- 协程,greenlet原生协程库, gevent库
协程简介 协程(coroutine),又称为微线程,纤程,是一种用户级的轻量级线程.协程拥有自己的寄存器上下文和栈. 协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来时,恢复之前保存的上下文 ...
- [cogs731] [网络流24题#6] 最长递增子序列 [网络流,最大流]
[转hzwer]第一问是LIS,动态规划求解,第二问和第三问用网络最大流解决.首先动态规划求出F[i],表示以第i位为开头的最长上升序列的长度,求出最长上升序列长度K.1.把序列每位i拆成两个点< ...
- 用sqlldr导入csv文件
1.新建文件test.ctl,内容如下 load dataCHARACTERSET 'UTF16' \*指定编码格式,很重要*\ infile 'vodall.csv' append into tab ...
- 在Centos安装oracle_11gR2进度68%"Error in invoking target mkldflags ntcontab.o nnfgt.o of makefile..”
http://www.xwood.net/_site_domain_/_root/5870/5874/t_c265367.html
- 递归算法详细分析->C
C通过运行时堆栈支持递归函数的实现.递归函数就是直接或间接调用自身的函数. 许多教科书都把计算机阶乘和菲波那契数列用来说明递归,非常不幸我们可爱的著名的老潭老师的<C语言程序设计> ...
- N天学习一个linux命令之xargs
用途 标准输入流读取参数(空格或者换行符分隔),传递给需要执行的命令 用法 xargs [options] [command [initial-arguments]] 常用选项 --arg-file= ...
- 优化实例- not in 和 not exists
客户运行一个SQL,非常慢.于是进行了一下改写.速度飞快,首先看一下原来的SQL. original sql SQL> explain plan for 2 select count(*) fr ...
- Error-MySQL:2005 - Unknown MySQL server host 'localhost'(0)
ylbtech-Error-MySQL:2005 - Unknown MySQL server host 'localhost'(0) 1.返回顶部 1. 今天在外面开navicat for mysq ...
- 第14课 SourceTree程序操作介绍
http://www.atlassian.com/software/sourcetree/overview https://www.microsoft.com/net/framework/versio ...