为什么编译器会警告隐藏初始化列表中的成员?
Why does the compiler warn about shadowing a member in initalization lists?
采用与正在初始化的数据成员具有相同标识符的构造函数参数。如果两者都用在一个初始化列表里面,就认为是安全的,不会出现"shadowing"。
但是,举个例子:
struct A{
A(int a, int b);
int a, b;
};
A::A(int a, int b)
: a(a)
, b(b)
{}
int main(){}
使用 g++ 看到的警告:
g++ -Wshadow --std=c++1z -o main main.cpp
main.cpp: In constructor ‘A::A(int, int)’:
main.cpp:8:18: warning: declaration of ‘b’ shadows a member of ‘A’ [-Wshadow]
A::A(int a, int b)
^
main.cpp:4:10: note: shadowed declaration is here
int a, b;
^
main.cpp:8:18: warning: declaration of ‘a’ shadows a member of ‘A’ [-Wshadow]
A::A(int a, int b)
^
main.cpp:4:7: note: shadowed declaration is here
int a, b;
用 clang 看到的警告:
clang++ -Wshadow --std=c++1z -o main t.cpp
main.cpp:8:10: warning: declaration shadows a field of 'A' [-Wshadow]
A::A(int a, int b)
^
main.cpp:4:7: note: previous declaration is here
int a, b;
^
main.cpp:8:17: warning: declaration shadows a field of 'A' [-Wshadow]
A::A(int a, int b)
^
main.cpp:4:10: note: previous declaration is here
int a, b;
我没有对构造函数主体中的数据成员执行任何操作——那么为什么我会收到这些警告?
我想启用警告标志以捕捉合法的事故,但这些特殊情况导致了太多错误的噪音。这些警告是否有效?
它抱怨是因为 a(a)
和 b(b)
- 结构成员的名称应与构造函数的参数名称不同。然后构造看起来像 mA(a)
和 mB(b)
虽然您现在没有做任何阴影可能会伤害您的事情,但您正在为一些维护问题设置自己。
如果维护者 Joe 出现并且需要进行如下更改:
A::A(int a, int b)
: a(a)
, b(b)
{
storeReference(a);
}
糟糕!他只是存储了对参数而不是数据成员的引用。
编译器并没有告诉你你本身做错了什么,它只是告诉你你可能想要更改你的名字,这样你以后就不会遇到问题了。
我个人建议选择一种命名约定来消除歧义并坚持使用。我个人喜欢把m_
放在member data的前面,但是其他人更喜欢在member data或者constructor param后面加上_
。
采用与正在初始化的数据成员具有相同标识符的构造函数参数。如果两者都用在一个初始化列表里面,就认为是安全的,不会出现"shadowing"。
但是,举个例子:
struct A{
A(int a, int b);
int a, b;
};
A::A(int a, int b)
: a(a)
, b(b)
{}
int main(){}
使用 g++ 看到的警告:
g++ -Wshadow --std=c++1z -o main main.cpp
main.cpp: In constructor ‘A::A(int, int)’:
main.cpp:8:18: warning: declaration of ‘b’ shadows a member of ‘A’ [-Wshadow]
A::A(int a, int b)
^
main.cpp:4:10: note: shadowed declaration is here
int a, b;
^
main.cpp:8:18: warning: declaration of ‘a’ shadows a member of ‘A’ [-Wshadow]
A::A(int a, int b)
^
main.cpp:4:7: note: shadowed declaration is here
int a, b;
用 clang 看到的警告:
clang++ -Wshadow --std=c++1z -o main t.cpp
main.cpp:8:10: warning: declaration shadows a field of 'A' [-Wshadow]
A::A(int a, int b)
^
main.cpp:4:7: note: previous declaration is here
int a, b;
^
main.cpp:8:17: warning: declaration shadows a field of 'A' [-Wshadow]
A::A(int a, int b)
^
main.cpp:4:10: note: previous declaration is here
int a, b;
我没有对构造函数主体中的数据成员执行任何操作——那么为什么我会收到这些警告?
我想启用警告标志以捕捉合法的事故,但这些特殊情况导致了太多错误的噪音。这些警告是否有效?
它抱怨是因为 a(a)
和 b(b)
- 结构成员的名称应与构造函数的参数名称不同。然后构造看起来像 mA(a)
和 mB(b)
虽然您现在没有做任何阴影可能会伤害您的事情,但您正在为一些维护问题设置自己。
如果维护者 Joe 出现并且需要进行如下更改:
A::A(int a, int b)
: a(a)
, b(b)
{
storeReference(a);
}
糟糕!他只是存储了对参数而不是数据成员的引用。
编译器并没有告诉你你本身做错了什么,它只是告诉你你可能想要更改你的名字,这样你以后就不会遇到问题了。
我个人建议选择一种命名约定来消除歧义并坚持使用。我个人喜欢把m_
放在member data的前面,但是其他人更喜欢在member data或者constructor param后面加上_
。