构造函数参数和具有相同名称的成员

时间:2017-05-13 15:09:59

标签: c++ oop language-lawyer initialization-list

我很好奇以下代码是否有效。静态分析在此构造函数上给出错误。

  

摘要:会员变量' A'是自己初始化的。

     

摘要:会员变量' B'是自己初始化的。

     

摘要:会员变量' C'是自己初始化的。

class Foo
{
public:
    Foo(int A, int B, int C);
private:
    int A;
    int B;
    int C;
}

Foo::Foo(int A, int B, int C) : 
A(A),
B(B),
C(C)
{}

我知道这不是一个好的做法,应该可以改变,但是我想知道静态分析警告是否是误报,并且成员变量将被正确初始化。

3 个答案:

答案 0 :(得分:2)

按照初始化列表中的说明,它们将被正确初始化。

确实,编译代码会给出:

Georgioss-MacBook-Pro:~ gsamaras$ g++ -Wall main.cpp
main.cpp:6:9: warning: private field 'A' is not used [-Wunused-private-field]
    int A;
        ^
main.cpp:7:9: warning: private field 'B' is not used [-Wunused-private-field]
    int B;
        ^
main.cpp:8:9: warning: private field 'C' is not used [-Wunused-private-field]
    int C;
        ^
3 warnings generated.

这些警告当然是无关紧要的。

进一步阅读:Initializing member variables using the same name for constructor arguments as for the member variables allowed by the C++ standard?

  

我知道这不是好习惯。

这也不错。权衡是你不引入新名称(例如通常看到的大写/小写的东西)。我认为这是一个意见问题。

答案 1 :(得分:2)

是的,这是误报:在为成员初始化列表计算表达式时,构造函数参数优先于成员;同时,构造函数参数不参与成员名称的解析过程,因此一切都与您期望的完全一致。

你认为这是一种不好的做法也是完全有效的。

答案 2 :(得分:2)

这非常有效,因为它们位于不同的范围内。对于成员初始值设定项列表A(A),第一个A位于类的范围内,然后将找到数据成员A;第二个A(放在括号中)在构造函数的范围内,然后将找到参数A(并隐藏具有相同名称的数据成员)。

标准引用,

$15.6.2/2 Initializing bases and members [class.base.init]

  

在mem-initializer-id中,在构造函数的类的范围内查找初始的非限定标识符,如果在该范围内找不到,则在包含构造函数的范围内查找该标识符'定义。

$15.6.2/15 Initializing bases and members [class.base.init]

  

mem-initializer的expression-list或braced-init-list中的名称   在构造函数的范围内进行评估   指定了mem-initializer。 [实施例:

class X {
  int a;
  int b;
  int i;
  int j;
public:
  const int& r;
  X(int i): r(a), b(i), i(i), j(this->i) { }
};
     

初始化X​::​r以引用X​::​a,初始化X​::​ b   构造函数参数i的值,用{初始化X​::​i   构造函数参数i的值,并用{初始化X​::​j   价值X​::​i;每次X类对象发生时都会发生这种情况   创建。 - 结束示例] [注意:因为mem-initializer是   在构造函数的范围内计算,this指针可以   在mem-initializer的表达式列表中用来引用   对象被初始化。 - 结束说明]