存储成员函数的位置

Where member functions are stored?

本文关键字:位置 函数 成员 存储      更新时间:2023-10-16

每当为一个类创建对象时,将为该类分配内存空间。所以我的问题是:内存创建仅为成员变量或成员函数也??如果内存是为成员函数创建的,那么它们将存储在哪里?

传统的可执行文件有三个部分。一个用于初始化数据,一个用于未初始化数据,还有一个用于代码。这种传统的分区仍然被广泛使用,并且代码,无论它来自哪里,都被放置在一个单独的部分中。

当操作系统将可执行文件加载到内存中时,它将代码放在内存中一个单独的位置,并将其标记为可执行文件(在现代内存保护系统中),并且所有代码都与对象本身分开存储在那里。

成员函数只是位于代码段中的代码。它们只存在一次,不管你有多少个对象。它们几乎与普通函数完全相同,除了它们的第一个参数是this指针,它隐藏在语言中,但在可执行代码中作为参数出现。

但是有两种成员函数:
  1. "正常"
  2. 虚拟

在代码大小的意义上它们之间没有区别,但是它们的叫法不同。对普通函数的调用可以由编译时确定,其他是通过函数指针的间接调用-

如果一个类有虚成员函数(类是"polymorph"),编译器需要为这个(不是object)创建一个"虚函数表"。

每个对象都包含一个指向其类的虚函数表的指针。如果对象是由基类类型的指针访问的,这对于访问正确的虚函数是必要的。

的例子:

class A{
public:  bool doSomething();
int i;
};
class B:public A {
public:  bool doSomething();
int j;
}
//
B b;
A* a = &b;
a->doSomething(); // <- A::doSomething() is called;
//

这两个类都不需要虚函数表。

示例2:

class A{
public:  virtual bool doSomething();
int i;
};
class B:public A {
public:  bool doSomething();
int j;
}
//
B b;
A* a = &b;
a->doSomething(); // <- B::doSomething() is called;
//

A(及其所有子节点)得到一个虚值表。然后创建一个对象,该对象的虚表指针被设置为正确的表,以便独立于指针的类型调用正确的函数。

只有成员变量(加上它们之间和后面的填充)对类的sizeof有贡献。

所以在这个意义上,正则函数不占用空间,就对象而言。成员函数只不过是普通的静态函数,有一个隐式的this指针作为隐藏参数。

尽管如此,虚函数表可能是实现处理多态类型的方式,这将占用一些空间,但可能只是指向该特定类的所有对象使用的表的指针。