关于 C++ 中的函数指针
About Function Pointer in C++
- 这几行意思一样吗?两者都没有任何警告消息!
int (*pFunc)() = func1; // I learned this is right.
int (*pFunc)() = &func1; // Works well with an ampersand too.
- 为什么我必须在这种情况下加上一个符号?没有它,不起作用!
int (CMyClass::*pMemberFunc)() = &CMyClass::memberFunc1;
- 为什么我必须为 类 中的函数指定命名空间,即使函数指针的类型完全匹配?
int (*pMemberFunc)() = CMyClass::memberFunc1; // Compiler error
int (*pMemberFunc)() = &CMyClass::memberFunc1; // Compiler error
- 为什么在这种情况下我不能指定命名空间?
namespace myNamespace {
int func1() {}
}
int (myNamespace::*pFunc)() = myNamespace::func1; // Compiler error
int (myNamespace::*pFunc)() = &myNamespace::func1; // Compiler error
int (*pFunc)() = &myNamespace::func1; // Works!
你的第一个问题,标准的法律术语:
A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed
in parentheses. [Note: that is, the expression &(qualified-id), where the qualified-id is enclosed in
parentheses, does not form an expression of type “pointer to member.” Neither does qualified-id, because
there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to
member function” as there is from an lvalue of function type to the type “pointer to function” (4.3). Nor is
&unqualified-id a pointer to member, even within the scope of the unqualified-id’s class. —end note ]
虽然乍一看似乎不一致,但我确实喜欢这样一个事实,即它使指向成员(无论是否为函数)的指针的语义等效。这在处理模板和 decltype 时肯定有好处。
对于第二个问题,您使用 CMyClass 限定了指针变量的范围,因为您的函数不是简单的“() -> int”函数:memberFunc1() 隐式传递了一个 CmyClass* 参数,您通常将其称为 "this".
如果您真的不能传递任何内容,那么您将丢失该方法正确执行其工作所需的信息(并且可能会崩溃)。如果您习惯于使用其他语言的 "delegates",请记住,如果方法不是 static/global.[=11,这些可以选择存储指向 "this" 对象的 "Target" 指针=]
至于第三个,它是一个独立的函数,所以它确实是 () -> int,但是你试图将你的指针限定在命名空间的范围内,而实际上你并没有在命名空间块。
虽然命名空间肯定会改变搜索符号的方式,但它根本不会影响函数的约定调用。
1)关于Q1,看下面的代码,由于func1是函数的右值,所以带或不带“&”都不会改变实际的函数地址。
看下面的代码:
#include <stdio.h>
void foo(){
printf("foo called\n");
}
int main(){
printf("%p\n", foo);
printf("%p\n", &foo);
void (*FUNC) ();
FUNC = foo;
FUNC();
printf("address %p\n", FUNC);
printf("address %p\n", &FUNC);
return 0;
}
输出是
0x101406eb0
0x101406eb0
foo called
address 0x101406eb0
address 0x7fff5e7f9a80
第二季度和第三季度)
指向成员函数的指针不是指针
你可以参考这里
https://www.safaribooksonline.com/library/view/c-common-knowledge/0321321928/ch16.html
- 这几行意思一样吗?两者都没有任何警告消息!
int (*pFunc)() = func1; // I learned this is right.
int (*pFunc)() = &func1; // Works well with an ampersand too.
- 为什么我必须在这种情况下加上一个符号?没有它,不起作用!
int (CMyClass::*pMemberFunc)() = &CMyClass::memberFunc1;
- 为什么我必须为 类 中的函数指定命名空间,即使函数指针的类型完全匹配?
int (*pMemberFunc)() = CMyClass::memberFunc1; // Compiler error
int (*pMemberFunc)() = &CMyClass::memberFunc1; // Compiler error
- 为什么在这种情况下我不能指定命名空间?
namespace myNamespace {
int func1() {}
}
int (myNamespace::*pFunc)() = myNamespace::func1; // Compiler error
int (myNamespace::*pFunc)() = &myNamespace::func1; // Compiler error
int (*pFunc)() = &myNamespace::func1; // Works!
你的第一个问题,标准的法律术语:
A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses. [Note: that is, the expression &(qualified-id), where the qualified-id is enclosed in parentheses, does not form an expression of type “pointer to member.” Neither does qualified-id, because there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to member function” as there is from an lvalue of function type to the type “pointer to function” (4.3). Nor is &unqualified-id a pointer to member, even within the scope of the unqualified-id’s class. —end note ]
虽然乍一看似乎不一致,但我确实喜欢这样一个事实,即它使指向成员(无论是否为函数)的指针的语义等效。这在处理模板和 decltype 时肯定有好处。
对于第二个问题,您使用 CMyClass 限定了指针变量的范围,因为您的函数不是简单的“() -> int”函数:memberFunc1() 隐式传递了一个 CmyClass* 参数,您通常将其称为 "this".
如果您真的不能传递任何内容,那么您将丢失该方法正确执行其工作所需的信息(并且可能会崩溃)。如果您习惯于使用其他语言的 "delegates",请记住,如果方法不是 static/global.[=11,这些可以选择存储指向 "this" 对象的 "Target" 指针=]
至于第三个,它是一个独立的函数,所以它确实是 () -> int,但是你试图将你的指针限定在命名空间的范围内,而实际上你并没有在命名空间块。
虽然命名空间肯定会改变搜索符号的方式,但它根本不会影响函数的约定调用。
1)关于Q1,看下面的代码,由于func1是函数的右值,所以带或不带“&”都不会改变实际的函数地址。 看下面的代码:
#include <stdio.h>
void foo(){
printf("foo called\n");
}
int main(){
printf("%p\n", foo);
printf("%p\n", &foo);
void (*FUNC) ();
FUNC = foo;
FUNC();
printf("address %p\n", FUNC);
printf("address %p\n", &FUNC);
return 0;
}
输出是
0x101406eb0
0x101406eb0
foo called
address 0x101406eb0
address 0x7fff5e7f9a80
第二季度和第三季度) 指向成员函数的指针不是指针 你可以参考这里 https://www.safaribooksonline.com/library/view/c-common-knowledge/0321321928/ch16.html