成员名称和构造函数参数名称之间的冲突

时间:2012-10-10 15:27:09

标签: c++ class arguments naming-conventions

  

可能重复:
  Members vs method arguments access in C++

我的班级有一些成员,例如xywidthheight。在它的构造函数中,我不会这样做:

A::A(int x, int y, int width, int height)
{
    x = x;
    y = y;
    width = width;
    height = height;
}

这没有用,当用g ++ x编译时,ywidthheight会变成奇怪的值(例如-1405737648

解决这些命名冲突的最佳方法是什么?

5 个答案:

答案 0 :(得分:17)

您可以使用相同名称的初始化列表:

A::A(int x, int y, int width, int height) :
    x(x),
    y(y),
    width(width),
    height(height)
{
}

另一种方法是使用不同的名称,如果您不想使用相同的名称。我想到了一些匈牙利符号的变化(我可能会对此感到讨厌):

//data members
int x_;
int y_;
int width_;
int height_;
//constructor
A::A(int x, int y, int width, int height) :
    x_(x),
    y_(y),
    width_(width),
    height_(height)
{
}

但第一个建议没有错。

答案 1 :(得分:5)

如果必须在构造函数中使用赋值(而不是使用首选项列表,这是首选),解决此问题的特定模式是使用this指针,如下所示:

this->a = a;

答案 2 :(得分:3)

如果可能的话,最好通过初始化列表设置数据成员,在这种情况下,影子成员名称的参数没有问题。另一种方法是在构造函数的主体中使用this->foo = foo;。 setter存在类似的问题,但现在您无法使用初始化列表解决方案。你被this->foo = foo;困住了 - 或者只是为参数和成员使用不同的名称。

有些人真的讨厌影子数据成员的论点;多个编码标准明确表示永远不要这样做。其他人认为这种阴影,至少对于建造者和制定者来说,是猫的喵喵。我记得读过一两个编码标准(但我不记得是哪一个)将这种阴影指定为“应该”(但不是“应该”)的做法。

最后一个选项是在函数声明中使用阴影,以便向读者提供关于函数功能的提示,但在实现中使用不同的名称。

更新:什么是“影子”?

#include <iostream>

void printi (int i) { std::cout << "i=" << i << "\n"; }

int i = 21; 

int main () {
   printi (i);
   int i = 42; 
   printi (i);
   for (int i = 0; i < 3; ++i) {
      printi (i);
      int i = 10; 
      printi (i);
   }
   printi (i);
}

iint i=10的最内层声明会隐藏i语句中声明的变量for,这反过来会影响在i声明的变量i函数范围,它反过来影响全局变量x

在手头的问题中,对{class 1}}的非默认构造函数的参数ywidthheightA会影响成员数据与这些参数的名称相同。

您的width=width;没有做任何事情,因为参数width遮蔽(隐藏)数据成员width。当您有两个或多个具有相同名称且在不同范围内声明的变量时,获胜者始终是具有最内部范围的名称。通常,它始终是赢得最内层范围的名称。

答案 3 :(得分:2)

虽然您可以通过使用构造函数的初始化列表来避免此问题,但我建议遵循命名数据成员的约定,例如,尾随_或前导m_。否则,您很可能会发生名称冲突,特别是如果您的成员名称为xy

class A
{
    public:

    A(int x, int y, int width, int height) : x_(x), y_(y), with_(width), height_(height) {}

    int x_;
    int y_;
    int width_;
    int height_;
};

答案 4 :(得分:0)

您只需更改构造函数参数的名称即可。当你写

A::A(int x, int y, int width, int height)
{
    x = x;
    y = y;
    width = width;
    height = height;
}

然后你将构造函数的参数分配给自己,将实际的实例变量保留为未初始化,这就是你得到虚假值的原因。

我建议(并广泛使用)的一般解决方案是更改构造函数方法的参数名称:

A::A(int x_initial, int y_initial, int width_initial, int height_initial)
{
    x = x_initial;
    y = y_initial;
    width = width_initial;
    height = height_initial;
}