为什么编译器会警告在初始化列表中隐藏成员?

时间:2016-01-20 09:05:56

标签: c++ g++ clang compiler-warnings

使用与其初始化的数据成员具有相同标识符的构造函数参数。如果在初始化列表中使用这两个,则认为它是安全的,并且不会发生“阴影”。

但是,请参考以下示例:

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;

我没有对构造函数体中的数据成员做任何事情 - 为什么我会收到这些警告?

我想启用警告标志以捕获合法的意外事件,但这些特殊情况会导致过多的虚假噪音。这些警告是否有效?

2 个答案:

答案 0 :(得分:15)

虽然你没有做任何阴影可能会伤害你现在的事情,但是你正在为自己设置一些维护问题。

如果Maintainer Joe出现并需要进行这样的更改:

A::A(int a, int b)
: a(a)
, b(b)
{
    storeReference(a);
}

糟糕!他只是存储了对参数的引用而不是数据成员。

编译器本身并没有告诉你你做错了什么,它告诉你你可能想要改变你的名字,这样你将来就不会有问题。

我会建议选择一种命名约定来消除歧义并坚持下去。就个人而言,我喜欢将m_放在成员数据的前面,但是其他人更喜欢将_加上成员数据或构造函数参数。

答案 1 :(得分:-3)

由于a(a)b(b)而抱怨 - 结构的成员名称应与构造函数的参数名称不同。然后构造看起来像mA(a)mB(b)