问题描述
据我所知,所有成员函数在类定义时都会在单独的内存中创建,并且对所有对象都是通用的。并且只为每个对象单独创建成员变量。但是使用对象调用时成员函数是如何执行的呢?
这些成员函数的地址将存储在哪里?
class B{
public:
int a;
void fun(){
}
};
int main(){
B b;
std::cout<<sizeof(b)<<std::endl;
}
如果我执行这个程序,我得到的输出为 4(仅用于成员变量)。但是调用 b.fun() 正确调用了它的成员函数。它如何调用而不将其地址存储在对象中?成员函数地址存放在哪里?
有没有类似类内存布局的东西来存储这些地址?
解决方法
非虚拟成员函数与普通的非成员函数非常相似,唯一的区别是它们之间的唯一区别是指向作为调用时第一个参数传递的类实例的指针。
这是由编译器自动完成的,因此(在伪代码中)您的调用 b.fun()
可以编译为
B::Fun(&b);
其中 B::Fun
可以看作是一个常用函数。该函数的地址不必存储在实际对象中(该类的所有对象都将使用相同的函数),因此该类的大小不包括在内。
有没有类似类内存布局的东西来存储这些地址?
对于声明为 virtual
的函数,是的。在这种情况下,所述函数的地址存储在表中并在运行时查找。这反过来又允许您的代码在调用函数时根据对象的类型分派到正确的函数。
非虚拟函数不能以这种方式工作。它们以与自由(即非成员)函数相同的方式存储,函数名以类名作为前缀。不需要对象本身的存储空间。
在这两种情况下,都会将隐藏的 this
指针传递给被调用函数。这就是将它“连接”到您的对象的原因。