为什么以下工作?
void foo() { cout << "Foo to you too!\n"; }; int main() { void (*p1_foo)() = foo; void (*p2_foo)() = *foo; void (*p3_foo)() = &foo; void (*p4_foo)() = *&foo; void (*p5_foo)() = &*foo; void (*p6_foo)() = **foo; void (*p7_foo)() = **********************foo; (*p1_foo)(); (*p2_foo)(); (*p3_foo)(); (*p4_foo)(); (*p5_foo)(); (*p6_foo)(); (*p7_foo)(); }
有几个部分允许所有这些运算符组合以相同的方式工作。
所有这些工作的根本原因是函数(如foo)可以隐式转换为指向函数的指针。这就是为什么void (*p1_foo)() = foo;起作用: foo被隐式转换为指向自身的指针,并且该指针被分配给p1_foo.
foo
void (*p1_foo)() = foo;
p1_foo
一元&应用于函数时,会产生一个指向函数的指针,就像它应用于对象时会产生对象的地址一样。对于指向普通函数的指针,由于隐式的函数到函数指针的转换,它总是多余的。无论如何,这就是为什么void (*p3_foo)() = &foo;有效。
&
void (*p3_foo)() = &foo;
一元*,当应用于函数指针时,会产生指向函数,就像它应用于指向对象的普通指针时会产生指向对象一样。
*
这些规则可以组合。考虑你的倒数第二个例子,**foo:
**foo
你可以添加任意多*的s,结果总是一样的。s越多*,越快乐。
我们还可以考虑您的第五个示例&*foo:
&*foo
但是,&它只能应用于函数,不能应用于已转换为函数指针的函数(当然,除非函数指针是变量,在这种情况下结果是指向指针的指针- to-a- function;例如,您可以添加到您的列表中void (**pp_foo)() = &p7_foo;)。
void (**pp_foo)() = &p7_foo;
这就是为什么&&foo不起作用: &foo不是函数;它是一个函数指针,它是一个右值。但是,&*&*&*&*&*&*foo会像 一样工作&******&foo,因为在这两个表达式中,&总是应用于函数而不是右值函数指针。
&&foo
&foo
&*&*&*&*&*&*foo
&******&foo
另请注意,您不需要使用一元*通过函数指针进行调用;两者都(*p1_foo)();具有(p1_foo)();相同的结果,同样是因为函数到函数指针的转换。
(*p1_foo)();
(p1_foo)();