对象的成员函数存储在哪里

Where are member functions stored for an object?

本文关键字:存储 在哪里 函数 成员 对象      更新时间:2023-10-16

我正在尝试用c++来理解类/结构和它们各自的对象是如何在内存中布局的,我理解类/结构的每个字段都是它们各自对象的偏移量(所以我可以有一个成员变量指针)。

我不明白为什么,即使我可以有成员函数指针,下面的代码不工作:

struct mystruct
{
    void function()
    {
        cout << "hello world";
    }
    int c;
};
int main() 
{ 
    unsigned int offset_from_start_structure = (unsigned int)(&((mystruct*)0)->c);
    unsigned int offset_from_start_structure2 = (unsigned int)(&((mystruct*)0)->function); // ERROR - error C2276: '&' : illegal operation on bound member function expression

    return 0;
}

我的问题是:为什么

unsigned int offset_from_start_structure = (unsigned int)(&((mystruct*)0)->c);

编译并返回"c"字段从结构开始到

行的偏移量
unsigned int offset_from_start_structure2 = (unsigned int)(&((mystruct*)0)->function);

甚至不能编译?

成员函数或指向它们的指针不存储在对象中。(virtual函数通常通过存储在表中的指针来调用,而对象有一个指向该表的指针)这将是一个巨大的内存浪费。它们通常存储在代码内存段中,并且编译器知道它们。对象(*this)通常作为不可见的参数传递,以便函数在调用时知道要操作哪个对象。

通俗地说,就是

 0x10001000    void A::foo
 ..........    {code for A::foo}

 push a;
 call A::foo (0x10001000)
 pop a;

其中a是您调用foo的对象

成员函数指针实际上不存储在对象中:没有必要。c++标准并没有具体规定如何实现虚函数,但虚成员函数的常见做法是每个对象包含一个指向函数指针表的指针;该指针称为虚表指针

你可以试着抓住“Inside c++ object model” by Stanley Lippman

或者,你可以试着找到我以前的指针教程,它曾经被引用自维基百科的指针文章,在我当时的主页消失之前。


关于第二个问题,为什么取p->memberFunc的地址会让编译器有点卡住,这个表达式没有类型,它只是一个语法实体,你可以应用一个参数列表来调用函数。

智慧

,

struct S
{
    void foo() {}
};
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
    S* p = 0;
    typeid( &p->foo );
} 
编译:

<>之前(W: 开发测试)> g++ foo.cppfoo.cpp:在函数'int main()'中:foo.cpp:12:17: error: ISO c++禁止使用绑定成员函数的地址作为指向成员函数的指针。说'&S::foo' [-fpermissive]foo.cpp:12:22:警告:value computed is not used [- unused-value]foo.cpp:12:22: warning: statement has no effect [- unused-value](W: 开发测试)> _