C++ 内存
1. 类对象的内存模型
在面向对象编程中,类是创建对象的蓝图,而对象则是类的具体实例。每个对象都有自己的内存模型,用于存储其数据成员(属性)和指向其方法的指针。下面简要介绍一个典型的类对象的内存模型,这里以C++为例:
-
数据成员(属性):
- 对象的数据成员直接存储在对象所占用的内存空间中。
- 每个数据成员根据其类型占用一定量的内存。例如,在32位系统上,int类型通常占用4个字节。
- 数据成员的排列顺序可能与它们在类中声明的顺序相同,但也可能因为编译器优化(如填充和对齐)而有所不同。
-
成员函数(方法):
- 成员函数并不是为每个对象单独复制一份,而是所有对象共享同一份代码。
- 类的非静态成员函数有一个隐含的第一个参数
this
,它是指向调用该成员函数的对象的指针。 - 静态成员函数不绑定到特定对象,因此没有
this
指针。
-
虚函数表(vtable):
- 如果类中包含虚函数,则会有一个虚函数表(vtable),其中包含了指向虚函数的指针。
- 每个对象都包含一个指向这个vtable的指针(vtbl_ptr),即使对象所属的类没有任何虚函数,但如果它的基类有虚函数的话。
- 这个指针通常位于对象内存布局的最开始位置。
-
静态成员:
- 静态数据成员不是存储在对象内部,而是被所有对象共享,并且是在全局或静态存储区中分配的。
- 因此,静态成员不会影响单个对象的大小。
-
继承和多态性:
- 在继承的情况下,派生类对象会首先包含基类对象的内存布局,然后是派生类自己添加的数据成员。
- 多重继承可能导致更复杂的内存布局,因为对象需要容纳多个基类的布局。
- 使用虚函数和多态性时,可能会引入额外的间接层,例如通过虚函数表来实现动态分派。
-
填充和对齐:
- 编译器可能会在数据成员之间插入“空洞”(即未使用的字节),以便按照目标平台的要求正确对齐数据,从而提高访问速度。
请注意,具体的内存布局细节取决于编译器实现和运行时环境,不同编程语言和平台上的实现可能会有所差异。上述描述是一个简化版的C++对象内存模型。如果你使用的是其他编程语言,比如Java、Python等,那么它们有自己的垃圾回收机制、对象分配策略和内存管理方式。