为何取非静态成员函数地址时&(A::m)无法正常工作?
为什么静态成员函数取地址加括号合法,非静态的却报错?
先看测试代码:
#include<iostream> class A { public: static void sm(){} void m(){} }; int main() { void (*fp1)() = &A::sm; // 1) 正常运行 void (*fp2)() = &(A::sm); // 2) 正常运行 void (A::*fp3)() = &A::m; // 3) 正常运行 void (A::*fp4)() = &(A::m); // 4) 错误:invalid use of non-static member function 'void A::m()' }
核心原因不是运算符优先级,而是C++对静态/非静态成员函数的语法规则差异:
对于静态成员函数
A::sm:它本质上和全局函数类似,只是被限定在类的命名空间下。A::sm本身是合法的函数名表达式,可以直接被取地址——不管加不加括号,&A::sm和&(A::sm)都是在取这个独立函数的地址,结果是普通的函数指针类型,所以两种写法都合法。对于非静态成员函数
A::m:它不能脱离对象独立存在,C不允许直接引用A::m这个“裸名”作为表达式。&A::m是C规定的专门语法,用来生成非静态成员函数指针,这个写法是一个整体,不能拆成&(A::m)——因为(A::m)本身就是非法的表达式,编译器无法识别一个脱离对象的非静态成员函数名,自然也就无法对它取地址。
简单总结:
- 静态成员函数可以当作普通函数看待,
类名::静态成员是合法的表达式,可直接取地址(加括号也没问题)。 - 非静态成员函数必须通过
&类名::非静态成员这个专用语法获取指针,不能单独写类名::非静态成员,所以加括号后取地址的写法不合法。
内容的提问来源于stack exchange,提问作者starriet 차주녕
相关产品推荐
相关产品推荐

