C++的方法列表是存放在哪里的?
在 C++ 中,成员函数的存储与管理方式与动态语言(如 Objective-C)不同。C++ 是静态类型语言,编译时就已经确定了函数的地址,所以并不存在一个专门的 "方法列表" 存放于内存中的结构。C++ 中的成员函数主要分为两类:普通成员函数和虚函数。这两类函数的存放方式不同。
1. 普通成员函数的存放
普通成员函数(非虚函数)在 C++ 中,并不与对象一起存储。它们的代码通常存放在程序的 代码段(text segment) 中,和全局函数类似。每个对象只是存储数据(成员变量),而函数的定义则是全局的。
在编译时,成员函数的地址已经被确定,并且对于每个类的对象,编译器直接使用函数的地址进行调用。普通成员函数的调用不会涉及额外的运行时开销。
存储细节:普通成员函数是与类的对象无关的,只是通过对象的调用语法来访问。因此,成员函数的代码实际存储在一个与类无关的全局代码段中。
2. 虚函数的存放
虚函数是 C++ 中支持 动态多态 的机制。对于带有虚函数的类,C++ 使用了一个称为 虚函数表(vtable) 的机制来支持运行时的动态方法调用。
虚函数表(vtable)
每个含有虚函数的类都有一个 虚函数表(vtable)。虚函数表是一个指针数组,数组中的每个元素都是虚函数的地址。
每个对象在其内存布局中包含一个指向虚函数表的指针(称为 vptr)。在调用虚函数时,程序通过对象的
vptr
查找到对应的虚函数表,从表中查找相应的函数地址并调用。vtable 的结构:每个类有一个虚函数表,表中记录了该类的所有虚函数的地址。当使用虚函数调用时,程序会根据对象的类型,从对应的虚函数表中查找具体的函数地址进行调用。这使得 C++ 支持动态多态(即基类指针或引用可以调用派生类的函数)。
vtable 的存储位置
虚函数表通常是由编译器在编译时创建并初始化的,表本身存储在静态内存中(全局数据段或静态内存区域),而
vptr
是存储在对象的内存中的一个指针。每个对象都有自己的vptr
,指向类的虚函数表。
3. 总结
普通成员函数:编译器在编译时确定它们的位置,并存储在程序的代码段中,与全局函数类似。调用时是直接跳转到函数的地址,不需要查表。
虚函数:通过虚函数表(vtable)机制进行管理。每个包含虚函数的类都有一个虚函数表,表中存储了虚函数的地址。对象通过虚函数表来实现动态多态。
虚函数表(vtable):存储在静态内存中,通常在全局数据段。
vptr:存储在每个对象的内存中,指向虚函数表。
通过这两种方式,C++ 实现了高效的静态成员函数调用和灵活的动态多态机制。
Last updated