获取class'方法地址

Getting class' method address

我请求你帮助我理解这个概念。也许我不明白什么,我不知道..所以我有这个示例代码:

#include <iostream>



class X{
    int a;
    public:
        void do_lengthy_work();

};

void X::do_lengthy_work(){
    std::cout << a << std::endl;
}

int main(){
    X my_x;    
    printf("%p\n", &X::do_lengthy_work); // -> does compile
    printf("%p\n", &my_x.do_lengthy_work); // -> doesn't compile,
    // error: ISO C++ forbids taking the address of a bound member function to 
    // form a pointer to member function. Say &X::do_lengthy_work
}

我在一本书中看到了这个代码示例。我认为我们无法获得 class' 方法的地址,除非指定了一个我们希望从中获取该函数地址的对象。但是结果只能得到一个class'的方法地址,而不能得到对象的方法地址。我认为每次我们声明一个 class 的对象时,它都有自己的方法,具有单独的地址。另外,如果我们这样做:

#include <iostream>



class X{
    int a;
    public:
        void do_lengthy_work();
        int b;

};

void X::do_lengthy_work(){
    std::cout << a << std::endl;
}

int main(){
    X my_x;
    printf("%p\n", &X::do_lengthy_work);
    printf("%p\n",&X::b);
    printf("%p",&my_x.b);
}

示例输出为:

0x562446a9c17a
0x4
0x7ffe7491a4cc

class 方法和对象的变量地址都改变了。但是b的变量地址没有变。它总是 0x4,距离 0x00 远 4 个字节,因为它是一个 int 变量。但是为什么它的地址离0x00那么近,而函数的地址却离它那么远呢?另外 - 重复我之前代码示例中的问题 - 为什么我们不能获得绑定成员函数的地址,但我们可以获得 class' 方法?

例如我们可以这样做:

&X::method

但不是这个:

&object.method

我开始思考 - 如果我是对的,你能纠正我吗? - 来自 class 的变量在声明 class 时被初始化一次(因此我们在打印出 X::b 地址时看到地址 0x4),然后(唯一地)每隔一段时间我们指定一个新对象(因此当打印出 my_x.b 的地址时我们看到 0x7ffe7491a4cc),但是方法只初始化一次并且每个对象都使用相同的方法,该方法总是在相同的地址上?

你基本上可以认为 X 是这样实现的:

struct X{
    int a;
    int b;
};
void X__do_lengthy_work(X* this);

方法与普通函数几乎相同,只是添加了指向 class.

实例的指针的隐藏参数。

class 的每个实例都使用相同的方法。

使用指向特定实例的方法的指针可能会产生误导,因为这可能意味着您可以调用该方法而不必提供实例,我想这就是语言不允许您这样做的原因那。