8

可能重复:
C++ 中的成员与方法参数访问

我有一个有一些成员的类,比如x、和。在它的构造函数中,我不会这样做:ywidthheight

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

这实际上没有意义,并且当使用 g++ xy、编译width时会height变成奇怪的值(例如-1405737648)。

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

4

5 回答 5

18

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

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)
{
}

但是第一个建议没有错。

于 2012-10-10T15:28:18.673 回答
5

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

this->a = a;
于 2012-10-10T15:32:01.527 回答
4

如果可能的话,最好通过初始化列表设置数据成员,在这种情况下,隐藏成员名称的参数没有问题。另一种选择是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);
}

, 的最里面的声明遮蔽了语句中声明的变量i,这反过来又遮蔽了在函数范围内声明的变量,进而遮蔽了全局变量。int i=10iforii

在手头的问题中,类的非默认构造函数的参数xywidth和隐藏了与这些参数同名的成员数据。heightA

width=width;什么也没做,因为参数width隐藏(隐藏)了 data member width。当您有两个或多个在不同范围内声明的具有相同名称的变量时,获胜者始终是具有最内层范围的名称。通常,获胜的总是具有最内部范围的名称。

于 2012-10-10T15:59:54.567 回答
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_;
};
于 2012-10-10T15:31:27.397 回答
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;
}
于 2012-10-10T15:34:27.137 回答