class A
{
private:
int a;
public:
class B
{
public:
B(int a) : b(a) {}
int b;
};
};
int main(void)
{
return 0;
}
clang(-Weverything)警告:
t.cpp(10,15): warning: constructor parameter 'a' shadows the field 'a' of 'A' [-Wshadow-field-in-constructor]
10 | B(int a) : b(a)
| ^
t.cpp(4,9): note: previous declaration is here
4 | int a;
我知道,由于C++11嵌套类可以像朋友一样访问外部类,但B只是在A内部声明(A中没有B的成员对象,B构造函数如何param ashadow A成员a ?
Namelookup 不需要
A
中的 B
实例。因为 B
嵌套在 A
内,不合格的名称查找会找到 A::a
。
来自cppreference:
对于类定义中任何地方使用的名称(包括基类说明符和嵌套类定义),成员函数体、成员函数的默认参数、成员函数的异常规范或默认成员初始值设定项内部除外,其中成员可能属于嵌套类,其定义位于封闭类的主体中,搜索以下范围:
a) 类的主体,在使用之前使用该名称,
b) 其基类的整个主体,当未找到声明时递归到其基类,
c) 如果此类是嵌套的,则包含外围类的主体直到此类的定义以及外围类的基类的整个主体, [...]
此时封闭类是友元并不重要,因为访问是在名称查找之后进行的。正如 Jarod42 所指出的,您可以修改代码以查看实际的阴影效果,因为
A::a
是非静态的,因此会出现错误。您的代码之所以有效,是因为在成员初始值设定项列表中 a(a)
使用构造函数参数 B::a
明确地初始化 a
。在构造函数中 a
指的是构造函数参数。如果您重命名参数,则 a
将引用 A::a
(导致错误,因为 A::a
是非静态的)。