实例化C ++类时,内存中会发生什么

时间:2010-04-27 00:24:03

标签: c++ memory

我对C ++的第一部分感兴趣,并且我想知道在实例化对象时实际发生了什么变化。我特别感兴趣的是,如果函数随后被添加到内存中,如果它们来自运行时,或者根本不存储在内存中。

如果有人能指导我使用C和C ++的一些核心螺栓上的好网站,我也会喜欢它。

谢谢, 乔

5 个答案:

答案 0 :(得分:8)

不确定网站是否合适,但Inside The C++ Object Model是一本非常好的书。

至少在通常情况下,成员函数完全独立于类的任何实例。相反,类的实例是包含对象的(非静态)数据成员的结构。如果该类至少具有虚函数,则该对象还将包含指向vtable的指针,该指针基本上是指向函数的指针数组。

当调用成员函数时,该对象的地址作为隐藏参数传递给函数(许多编译器只保留一个寄存器),在函数中它被称为 this

答案 1 :(得分:1)

这些函数都存储在可执行文件本身中,因此它们从一开始就被加载。

该对象为成员变量所需的任何内存都已分配。

如果你想知道函数如何知道它被调用的对象,基本上有一个不可见的“this”指针作为第一个参数传递给函数。

答案 2 :(得分:0)

实例化对象时

  1. 分配内存
  2. 构造函数已执行
  3. vtable是“设置”
  4. Number 3是构造函数无法在派生类中调用虚函数的原因(当执行构造函数时,vtable尚未“设置”)。

    使用字母/信封成语可以获得相同的效果。有关此内容,请参阅Advanced C++ Programming Styles and Idioms

答案 3 :(得分:0)

常见的情况是:

  1. 通过调用operator new来分配内存。这个功能很可能已经在内存中,它需要很多。
  2. 调用类的构造函数。这段代码已经存在于内存中。如果没有,则调用此函数页面 - 出错。操作系统会记录并将可执行文件中的相应页面加载到RAM中。然后它告诉操作系统重试。 (2A。ctor安排虚拟函数可以调用 - 通常通过编写vtable指针)
  3. 可能是包含构造函数的页面还包含类的其他成员。那些也可以被称为。但是如果它们在另一个页面上,则调用它们可能会导致另一个页面错误和另一个负载。如果您的编译器将vtable放在不同的页面上,则使用该vtable也可能导致页面错误。
  4. 这种按需加载机制的优点是,如果用户从不打算打印他的文档,操作系统可以避免加载类CPrinter的代码。

答案 4 :(得分:0)

通常,在实例化类时,会分配新的内存块。分配的内存包含:

  1. 类的非静态数据成员和基类的继承非静态数据成员。
  2. 如果类有一个或多个虚函数,那么类实例还包含指向该类的virtual function table的指针。
  3. 创建新实例时,不会复制类的功能。 This将有助于了解构成对象大小的原因。