为什么指向非常量成员函数的指针不能指向常量成员函数和相反的函数?

Why pointer to non-const member function can't point const member function and opposite?

本文关键字:函数 成员 常量 不能 为什么 指针 非常      更新时间:2023-10-16
指向

成员函数的指针不能指向常量成员函数的原因是什么?

struct A {
    void g() {};
    void f() const {}
};

后面的代码:

void (A::* fun)() = &A::f;

此代码生成:

error: cannot convert ‘void (A::*)()const’ to ‘void (A::*)()’ in initialization

当然,它是用&A::g而不是&A::f编译的。

在相反的情况下:

void (A::* fun)() const = &A::g;

错误是:

error: cannot convert ‘void (A::*)()’ to ‘void (A::*)()const’ in initialization

第二种情况相当清楚。 const指针不应修改对象,因此它无法容纳执行此操作的函数。但是,为什么不能像第一种情况那样将const成员函数分配给non-const成员函数呢?

看起来就像普通指针的规则,其中将const转换为non-const将允许修改值,但我在这里看不到这一点,在这种分配之前,在函数定义中检查常量正确性。

指向成员函数

的指针不能指向常量成员函数的原因是什么?

因为 const 修饰符是函数签名的一部分。声明函数指针后,该函数指针只能用于将指针分配给具有相同函数签名的函数。

非静态成员函数有一个额外的隐藏this参数。鉴于存在该额外隐藏参数,非静态void A::f() const;的行为与void A__f(const A *__this)非常相似,并且您看到的成员函数的行为模拟了非成员函数的行为。

void f(void *);
void (*pf)(const void *) = f; // also an error

至于它是否可以在任何实现上中断,我想理论上,允许实现从与const void *参数不同的寄存器中读取void *参数,如果是这样,转换的结果(如果有效)不能用于正确调用f。我不知道为什么任何实现者都会做出这样的决定,我也不知道有任何真正的实现会这样做,但这是标准允许的。