一、类对象的内存布局

1.1、单一继承的类对象布局

示例1

class base
{
public:int m_fai;int m_faj;
};
class derive : public base
{
public:int m_i;int m_j;
};int main()
{base b;derive d;cout<<showbase;cout<<hex<<&b.b_i<<endl;cout<<&b.b_j<<endl;cout<<&d.b_i<<endl;cout<<&d.b_j<<endl;cout<<&d.d_i<<endl;cout<<&d.d_j<<endl;return 0;
}

根据上述输出结果可以画出如下对象内存布局

示例2

class base1
{
public:int b1_i;char b1_c;
};class base2 :public base1
{
public:char b2_c;
};class base3 :public base2
{
public:char b3_c;
};int main()
{base3 b3;cout<<showbase;cout<<hex<<&b3.b1_i<<endl;cout<<&b3.b1_c<<endl;cout<<&b3.b2_c<<endl;cout<<&b3.b3_c<<endl;cout<<sizeof(base1)<<endl; cout<<sizeof(base2)<<endl;cout<<sizeof(b3)<<endl;
}

对象内存模型如下

通过上述模型可知,正常情况下,继承会增加对象所占的内存数,许多内存要用于内存补齐,增大程序的体积

1.2、单一含有虚函数的类对象布局

class base
{
public:virtual void vfunc() {}int bi;
};int main()
{base b;printf("%d\n", &b);printf("%d\n", &b.bi);cout<<sizeof(base)<<endl; }

1.3、单继承基类含有虚函数的内存布局

class base
{
public:virtual void vfunc() {}int bi;
};class derive :public base
{
public:int di;int dj;
};int main()
{derive d;printf("%d\n", &d);printf("%d\n", &d.bi);printf("%d\n", &d.di);printf("%d\n", &d.dj);cout<<sizeof(d)<<endl;
}

1.4、单继承基类含有虚函数的内存布局

class base
{
public:int bi;
};class derive :public base
{
public:int di;int dj;virtual void vfunc() {}
};int main()
{derive d;printf("%d\n", &d);printf("%d\n", &d.bi);printf("%d\n", &d.di);printf("%d\n", &d.dj);cout<<sizeof(d)<<endl;}

对象内存布局同1.3

无论虚函数位于基类还是子类,对于单一继承来说,vptr都位于对象的最上方

1.5、多重继承的对象内存布局

class base
{
public:virtual void b1vfunc() {}int m_bi;base(){printf("base的this指针是:%p!\n", this);}
};class base2
{
public:virtual void b2vfunc() {}int m_b2i;base2(){printf("base2的this指针是:%p!\n", this);}
};class derive :public base, public base2
{
public:int m_i;int m_j;virtual void dvfunc(){}derive() {printf("derive的this指针是:%p!\n", this);}
};int main()
{derive d;cout << sizeof(derive) << endl;printf("derive::m_bi = %d\n", &d.m_bi);printf("derive::m_b2i = %d\n", &d.m_b2i);printf("derive::m_i = %d\n", &d.m_i);printf("derive::m_j = %d\n", &d.m_j);}

因为多重继承需要额外的内存存放vptr以及可能因为内存补齐而耗费多余的内存,所以,多重继承的代码占内存空间比一般继承要大

参考

《深度探索C++对象模型》

《C++新经典:对象模型》

欢迎大家评论交流,作者水平有限,如有错误,欢迎指出

C++对象模型5——类对象的内存布局相关推荐

  1. C++类对象在内存中的布局

    目录 一.前言 二.C++ 类对象的内存布局 2.1 只有数据成员的对象 2.2 没有虚函数的对象 2.3 拥有仅一个虚函数的类对象 2.4 拥有多个虚函数的类对象 三.继承关系中的C++类对象内存分 ...

  2. c++对象模型05:虚继承内存布局

    虚继承 虚继承解决了菱形继承中最派生类拥有多个间接父类实例的情况.虚继承的派生类的内存布局与普通继承很多不同,主要体现在: 虚继承的派生类,如果定义了新的虚函数,则编译器为其生成一个虚函数指针(vpt ...

  3. C++中的类对象的内存分布以及虚函数表内存分布

    ​ 目录 目录 一.前言 二.C++ 类对象的内存布局 三.函数调用 一.前言 C++的精髓是虚函数.虚函数带来的好处就是:可以定义一个基类的指针,其指向一个继承类,当通过基类的指针去调用函数时,可以 ...

  4. 深入理解C++对象模型-对象的内存布局,vptr,vtable

    vtpr的位置:        为了支持多态,C++引入了vtpr和vtable这两个概念.对于每个有虚函数的类,C++都会为其生成一个vtable,并在类中添加一个隐含的数据成员vptr. 对于vp ...

  5. C++ 对象的内存布局(上)

    原文地址:http://blog.csdn.net/haoel/article/details/3081328 为尊重原作者的创作成果,所以原文全部内容都会保留,但是会适当添加我的理解. 前言 07年 ...

  6. C++ 对象的内存布局

    C++ 对象的内存布局(上) 陈皓 http://blog.csdn.net/haoel 前言 07年12月,我写了一篇<C++虚函数表解析>的文章,引起了大家的兴趣.有很多朋友对我的文章 ...

  7. c++对象的内存布局2--进阶篇---C++ 对象的内存布局(上)

    目录(?)[-] 前言 对象的影响因素 知识复习 单一的一般继承 多重继承 前言 07年12月,我写了一篇<C++虚函数表解析>的文章,引起了大家的兴趣.有很多朋友对我的文章留了言,有鼓励 ...

  8. C++虚继承(二) --- C++ 对象的内存布局(上)(陈皓)

    C++ 对象的内存布局(上) 陈皓 http://blog.csdn.net/haoel 点击这里查看下篇>>> 前言 07年12月,我写了一篇<C++虚函数表解析>的文 ...

  9. 动态加载laydate 失效_Java对象的内存布局+反射的原理+动态代理+ 并发和锁+文末彩蛋...

    # 一行代码是怎么运行的 首先,java代码会被编译成字节码,字节码就是java虚拟机定义的一种编码格式,需要java虚拟机才能够解析,java虚拟机需要将字节码转换成机器码才能在cpu上执行. 我们 ...

最新文章

  1. 非此即彼的逻辑错误_MBA逻辑攻略-逻辑知识大全,快来收藏吧!
  2. Windows下更改pip镜像源
  3. i.mx6ul 移植Openwrt
  4. 如何下载SAP Intelligent Robotic Process Automation相关的软件
  5. JMS-activMq与spring进行整合
  6. GHOSTXP_SP3电脑公司快速安装机版V2013
  7. navision系统和sap区别_erp系统与sap的区别是什么?
  8. 各浏览器对focusin/focusout事件的支持差异
  9. appium python api
  10. 理解 MeasureSpec
  11. 什么是测试开发工程师(SET)?
  12. 前端克隆数据 --JS 深浅拷贝
  13. 从0开发豆果美食小程序——tag组件
  14. springboo集成bboss-elasticsearch实现elasticsearch客户端
  15. 【马修笔记】大波段顶底反转的节奏交易.
  16. 百度关键词分析工具_百度网站关键词快排系统 - 网站被降权的原因分析
  17. ExtAspNet v3.1.3
  18. 深度学习模型部署-triton
  19. 号码保护AXB功能!(精华)
  20. 【NOJ1325】【算法实验三】【分支限界法】特殊的二阶魔方

热门文章

  1. P1064 金明的预算方案
  2. netty源码分析系列——EventLoop
  3. zabbix_监控_进程
  4. Thinkphp动态切换主题
  5. php实战第二十一天
  6. python读取压缩包中csv文件
  7. Markdown矩阵、表格和数学公式
  8. 十年架构师详解,Spring-IoC容器装配Bean
  9. 进程和线程的区别?什么时候用进程?什么时候用线程?
  10. git解决代码提交冲突