成员函数指针

时间:2010-10-24 14:25:09

标签: c++ member-function-pointers member-pointers

如果C ++ FAQ Lite中的以下内容为真:“函数名称衰减为指向函数的指针”(因为数组名称衰减为指向其第一个元素的指针);为什么我们必须加入&符号?

typedef  int (Fred::*FredMemFn)(char x, float y);
FredMemFn p = &Fred::f;

而不只是:

typedef  int (Fred::*FredMemFn)(char x, float y);
FredMemFn p = Fred::f;

在第二种情况下,Fred :: f是一个函数,可以衰减到指向该函数的指针。

我希望这个问题不是那么愚蠢。

1 个答案:

答案 0 :(得分:17)

原始答案:

因为成员函数不是函数而成员函数指针不是函数指针。因此,衰变规则不适用。

此外,C ++中有函数类型,但不是成员函数类型。因此,您可以在需要指向函数的位置使用函数,但是您不能使用成员函数,因为没有这样的东西,只有指向成员函数的指针。你的例子中的f是一个函数。另一方面,Fred :: f是......好吧,没什么。

另外,我认为“函数的名称可以衰减......”。不,名称不能做任何事情,函数类型的左值可以隐式转换为指向函数的指针,就重载解析而言,这是一个身份转换

编辑以澄清我的回答:

C ++中的每个表达式都有一个类型和值。偶尔可以将一种类型的值转换为另一种类型的值。对这些转换进行排序,以使一次转换更好,另一次转换主要用于函数重载解析。

其中一种转换类型称为左值到右值转换。当左值出现在需要右值的上下文中时,将发生此转换。通常这种转换什么都不做,例如:

int i = 4, j = 5;
i = j;
第二行上的

是一个左值,但这里需要一个右值,因此j被转换为右值。但这不是一个可观察到的转换,是吗?但是有些情况下可以观察到左值到右值的转换。也就是说, n T数组的左值可以转换为T*类型的右值,其值是数组的第一个元素的地址 类型为“具有签名S的函数”的左值“类型为”具有签名S的函数的指针“的右值,其值为函数的地址

这意味着当我们将函数赋值给函数指针时,函数lvalue会隐式转换为它的地址。

void f() {}
void (*p) () = f; //f is converted to rvalue

f是一个表达式并且有一个类型。 f的类型是void()

C ++中没有member-function 这样的类型 有指向成员函数的指针,但不是成员函数本身。我当然在谈论非静态功能。静态函数的工作方式与普通函数相同,也就是说,您不必编写&X::f,而是可以编写X::f 为什么?因为X :: f具有类型函数并且发生上述转换。但是,如果f是非静态的,那么X :: f的类型是什么?哦,是的,它没有类型,因此不是表达式,因此没有值,因此该值不能转换为任何值。

引用标准:5.3.1第3条 指向成员的指针仅在显式&使用它的操作数是一个未括在括号中的限定id。 [注意:也就是说,表达式&(qualified-id),其中qualified-id括在括号中,不形成“指向成员的指针”类型的表达式。也不是qualified-id,因为没有隐含从非静态成员函数的qualified-id转换为“指向成员函数的指针”类型,因为从函数类型的左值到类型“指向函数的指针”(4.3)。也不是& nonqualified-id指向成员的指针,即使在范围内也是如此 unqualified-id的类。 ]

希望这更清楚......