【C++札记】C++对象模型之内存布局(1)

论坛 期权论坛 期权     
码农有道   2019-6-16 21:52   3374   0
如果想学习在linux或者在linux平台下开发,学习C/或C++是非常好的选择.俗话说,术业有专攻,学一门技术,就尽量学得深,也可以作为行走江湖,混口饭吃的一项本领.
对于C,当初我是看了C与指针这门书,这本书讲解了很多我没有了解过的知识点,特别是指针讲解的很到位.最后还设计了C运行时内存模型.
对于C++的学习,我看了C++ Primer之后,进阶的书为深入理解C++对象模型,这本书讲解了C++类在内存中是如何布局以及成员函数是怎么调用,有助于理解C++多态是如何实现的.总之,受益匪浅.
接下来,我将用几篇文章聊聊C++对象模型.


无多态的对象布局单个类:
假设有以下一个类的定义:



如果类没有虚函数,那么class的布局和c语言的struct布局一样,只有成员变量.对象内存布局如图1左所示.
继承类
如果有一个类B继承上面的类A,定义如下:



子类的构造函数是先构造父类,再构造子类,所以类B对象内存布局只要在A成员之后加上B的成员即可,示意图如图1右所示:


(图一)

多态下对象内存布局单个类:
首先定义一个类,带有虚函数:



因为class A带有虚函数,所以A对象的内存布局就要增加一个虚函数表指针,它是一个指针,指向类A的虚函数表.对象模型如图2上所示.深入理解C++对象模型将指针放在了对象的末尾,但是现在主流的编译器都将指针放在了对象的首位置.
单继承:
单继承类的定义如下:



当父类有虚函数时,子类继承父类的虚函数表,而且虚函数的顺序是先父类的虚函数,再子类的虚函数;当父类的虚函数被子类重写时,则虚函数表中的父类虚函数指针要替换为子类的虚函数指针,示意图如图2下.


(图二)

实例验证为了验证之前的对象模型是否正确,我写了如下程序进行验证:





稍微解释下



  • (long*)bp,将对象的指针类型转换为(long*)类型,用于取出虚函数表的地址.
  • *(long*)bp,*为取出指针指向的值.此式子即虚函数表的地址,也就是第一个虚函数的地址.
  • (long*)*(long*)bp,将虚函数表的地址指针转换为(long*),用于后续迭代.
  • *(long*)*(long*)bp,*求指针值,即为第一个虚函数的地址,最后转换为pfun指针.
该程序输出结果为:


输出顺序和上述一样.
多重继承,多继承以及菱形继承留在下一篇文章.

推荐阅读:
精心整理 | 历史干货文章目录[/url]

[url=https://mp.weixin.qq.com/s?__biz=MzIwNTc4NTEwOQ==&mid=2247483774&idx=1&sn=21f3963c57e61853d1e415ffae11bb77&chksm=972ad004a05d59126588d4f4724be869ad4481d0505a31005cc24f46cd38a5f77140e0444820&mpshare=1&scene=21&srcid=09021i75Vh2h1KY5Ab1P6viR#wechat_redirect]【福利】自己搜集的网上精品课程视频分享(上)


【系统架构】大型网站架构演化历程(上)
【系统架构】大型网站架构演化历程(下)
【数据结构与算法】 通俗易懂讲解 二叉树遍历

【数据结构与算法】 通俗易懂讲解 二叉搜索树

专注服务器后台技术栈知识总结分享
欢迎关注交流共同进步

码农有道 coding
码农有道,为您提供通俗易懂的技术文章,让技术变的更简单!
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:60
帖子:12
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP