类和类的方法存储在哪里?

时间:2013-07-16 05:05:42

标签: c++ oop

记忆可以分为4个区域。

首先是堆栈,第二个是堆,第三个是代码,最后一个是数据。

我想知道类和类的方法存储在哪里。

你能解释一下吗?

3 个答案:

答案 0 :(得分:2)

警告:从理论上讲,这个答案的部分内容可能有很大不同(但事实上,至少在大多数典型/常见的实施中,都存在一定程度的一致性)。因此,这个答案的部分内容主要基于您通常可以预期的内容,即使可能有更多变化。

“方法”(成员函数)是代码,与其他代码一起定位。与其他函数的主要区别在于成员函数通常期望接收隐藏参数(称为this),该参数为其提供任何对象数据的地址(包括间接地,类'vtable指针)。

类'数据的位置通常取决于如何分配类的对象,就像任何其他变量一样:全局或静态本地对象将被静态分配(在列表之外,显然是“数据”) ;将自动分配一个本地自动变量(也称为“在堆栈上”),并动态分配动态分配的变量(大惊喜)(也称为“在堆上”)。

当然,可以稍微改变这些规则 - 例如,无论对象的其余部分是如何分配的,都将静态分配static成员变量。

答案 1 :(得分:0)

一个类的定义存储在一个程序的代码部分(如果你考虑它,这是有意义的,因为该定义实际上是一组函数,从概念上将该对象作为一个名为“this”的附加参数)。但是,虚拟类的每个实例都需要包含一个指向其虚拟表的指针(为了能够执行动态调度),并且它将驻留在该实例恰好被分配的任何地方(对于虚拟情况,通常会在堆上。)

那些语言律师粘贴者会指出C ++标准并没有规定堆和堆栈之类的东西。我很清楚这一点,但出于所有实际目的,这就是它的运作方式。

答案 2 :(得分:0)

方法不占用实例存储。 OOP创建了一个错觉,某个方法是一个类成员对象,但这只是一个范例,实际上你可以将成员方法视为全局函数,只在它们“关联”的对象范围内可见。

简而言之,C ++成员方法SomeType.someMethod()与C SomeType结构和伴随的SomeType_someMethod(SomeType* self)相同,这是C ++编译器自动生成的。

实际占用实例数据空间的类的唯一部分是非静态成员类型。所以成员方法在逻辑上占据了内存的“代码”和“数据”部分,因为一个方法就是这样 - 一个指令列表和对内存中全局和本地对象的引用。

由于C ++允许递归和所有其他“动态特性”,函数的每个实例都实例化它自己的本地对象,因此非静态和非const本地自动成员从全局内存复制到堆栈,立即值的形式或对全局静态数据的引用。这仅适用于非const本地成员数据,a方法不会更改其指令,因此与locals不同,只需要方法代码的一个实例。

因此,为了将其包装起来,成员方法与静态成员对象一样不占用实例空间,但是,它们在调用时可能会占用堆栈空间,甚至可能导致在递归情况下堆栈溢出。

编辑:也许值得注意的是,在虚方法的情况下,将从每个对象占用一个空指针空间来容纳虚拟表。此外,大多数多继承实现通常会使用多个vtable。