为何C++类的私有成员在初始化静态变量时可见?
问题解答
以下代码能正常编译的核心原因是:类静态成员的类外定义处于该类的作用域范围内,且在这个上下文里,类的所有成员(包括私有成员)都是可访问的。
class Node{ int m = 0; static unsigned f(){ return 1; } public: static unsigned a; static unsigned b; }; unsigned Node::a = sizeof(m); // 合法 unsigned Node::b = f(); // 合法 int main(){ }
具体解释:
对于
sizeof(m):
在Node::a的定义语句中,编译器会将当前作用域绑定到Node类,因此m会被直接解析为Node::m。类成员的定义(包括静态成员的类外初始化)属于类的成员定义上下文,在这个上下文中,C++标准允许访问类的所有成员,不受访问权限(private/protected/public)的限制。即使sizeof不需要执行表达式,名字查找依然会在类作用域内完成,且权限检查通过。对于
f()的调用:
同理,Node::b的定义处于Node类的作用域内,f()会被解析为Node::f()。类成员定义上下文有权访问类的私有成员函数,因此直接调用私有静态函数f()是合法的。
关于Koenig查找(ADL)的补充:
这里不涉及Koenig查找。Koenig查找是针对函数调用时,额外查找参数类型所在命名空间的函数,而这里的f()没有参数,且当前作用域已经是Node类的作用域,名字查找优先匹配类的静态成员函数,和ADL无关。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

