C++类内存结构分析

 

本文的目标是阐述清楚C++的类相关的内存结构问题。

 

这个问题对于已经很了解的人来说,太简单了,这还有必要拿出来与人分享吗?但对于那些不了解的人,始终有一层窗户纸不能被捅破,似乎总是不能非常到位的理解本质。

 

本文的阐述过程会分为几个阶段,类与对象的关系,对象到底是什么,类的函数时如何被处理的,多态是如何被处理的,其中最核心的是对类函数的实质的理解。

 

1 类与对象的关系。

我们该如何理解类与对象的关系?那需要先了解什么是类,类是一个抽象的定义,包含了一组数据,一组对数据的操作。那么类与对象的关系,就类似于int与整形变量的关系,类仅仅定义了一种特殊的类型,它没有地址,所以程序中叶没有任何地方去存储一个类,而对象是一个类的实例化,是真实存在于内存中的,所以对象是有地址的。

 

2 对象到底是什么?

既然上一个问题提到了,对象是类的一种存在形式,是真实存在于内存中的,那么它到底是什么样子?如果大家查看下某个类对象的内存信息,会清楚的发现,对象的地址上顺序的存放着该对象内变量的值。这样说来,对象只是一个地址,该地址记录了一个数据块,而就是这个数据块代表了对象的存在。

 

3 类的函数如何被编译器处理?

我们要问自己一个问题,函数到底是什么?大家都知道,但请大家一定要深化这个概念,函数只是一片内存,一片记录了函数执行代码执行的内存,那么这样的话,函数指针也就很容易理解了,就是函数对应的内存的入口地址而已(对于想深入理解函数参数传递的朋友可以参见其它文章)。

类函数与C函数有何不同?类函数是属于某个类的,而C函数可以被任意调用,但事实真的是这样吗?类函数只能被该类调用吗?下面的代码证明不是该类的函数也是可以调用的。

***

那么如何解释上边的代码?A类中的函数为何也可以被B调用?这只有一个解释,那就是类在编译的时候,函数是全局的,类似于C函数。这样就可以完整的来看一个类对象在内存中的分布了,首先是一块数据区,存储了对象变量数据,其次是多个类函数对应的内存区,并且函数对应的内存不会因为创建另一个对象而发生变化。

这样,本质上来说,只要符号类函数的调用形式,任何一个对象都可以调用任何一个类函数,这样的手段可能在建立类处理映射上很有用吧。

 

4 多态是如何被处理的?

什么是多态?多态就是不同的类来说,可以有同一个函数定义的实现,并在具体调用时,能够根据类的类型找出该类对应的函数定义。

一般来说,对于pA->f1();这样的调用来说,函数调用的地址是在编译的时候确定了的(虽然地址那个时候是相对的),而如果f1是一个虚函数,具体真实的函数地址还不能获取到,这时该如何处理?

对于这个问题,大家可以先考虑考虑。

 

对于这个问题,我的想法就是在对象pA中记录下所有虚函数的相对地址,如果当前类没有实现,那么就记录基类的虚函数地址,确保每个虚函数都有对应的函数地址,在具体编译这样的语句时,就可以先检测是否为虚函数,如果是,则通过对象内读取的真实的虚函数地址来进行处理,事实上,通过调试发现C++编译器也确实是这么做的,例如VC中,是将变量的第一个指针记录了该类对应的虚函数数组,该数组记录了每个虚函数对应的地址。

 

 

因为我对问题的理解与大家对问题的理解角度不一样,或关注的重点不一样,如果大家有不清楚的地方,可以提出来,我会将我的努力与大家分享。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值