C++对象实例成员函数内存表示

Posted

技术标签:

【中文标题】C++对象实例成员函数内存表示【英文标题】:C++ object instance member function memory representation 【发布时间】:2015-05-29 10:34:43 【问题描述】:

C++ 中的成员函数究竟是如何在内存中表示的?我理解的功能基本上分为三种:

-静态:这些表示为任何其他全局函数

-Virtual:这些可以在运行时通过 vtable 访问,以执行动态调度。

-非静态和非虚拟:我在这里遇到了麻烦。大多数文章或解释说,它们的表示方式与代码中的普通函数相同,唯一的区别是它们期望隐藏的“this”指针作为参数,以便能够访问实例的数据。但是,我不太确定这是如何表示/实现的。例如,如果我有:

class A:
  int var_a;

  public:
   int get_member_var_a()
    return var_a;
   

   A(int init): var_a(init) 

 A* instance_of_a = new A(4);

现在如果我打电话

int tmp = instance_of_a->get_member_var_a();

对象A 的实例是否有一个指向函数get_member_var_a 的指针存储在内存中的某处,并且它只是调用该函数,同时将实例指针作为额外参数传递?

【问题讨论】:

去尝试一下python。在几个类的例子之后(实际上是在第一个之后),你就会明白我为什么派你去那里了。 我经常使用python ^^ 这就是那里发生的事情:python 中的成员函数是常规函数,其中第一个参数是对象本身 (__self__)。在 C++、java 等中,这种机制是隐藏的。 【参考方案1】:

您的第二个假设对于大多数实现来说可能是正确的。

int A::get_member_var_a() 很可能会被编译成类似的东西 int __internal_compiler_prefix___A___get_member_var___thiscall(A* this)

所有a->fun() 将被编译器“替换”为fun(a)

将地址存储在实例内部运行的开销太大(每个对象每个方法几个字节),因此甚至可能被标准禁止。

【讨论】:

【参考方案2】:

C++ 编译器会将非静态非虚拟函数转换为“新”函数。此外,“new”函数的第一个参数将是“this”指针。

 instance_of_a->get_member_var_a();

编译器会将上面的行转换为:

mangled_function_name_for_get_member_var_a(this)

例如,编译器可能会将函数修改为 _ZN1A16get_member_var_aEv。

【讨论】:

以上是关于C++对象实例成员函数内存表示的主要内容,如果未能解决你的问题,请参考以下文章

C++语法小记---面向对象模型(实例的内存分布)

C++面向对象编程:对象的内存分配与静态成员

C++面向对象编程:对象的内存分配与静态成员

C++|详解类成员指针:数据成员指针和成员函数指针及应用场合

类成员和成员函数内存位置

c++复习篇