我的班级有一些成员,例如x
,y
,width
和height
。在它的构造函数中,我不会这样做:
A::A(int x, int y, int width, int height)
{
x = x;
y = y;
width = width;
height = height;
}
这没有用,当用g ++ x
编译时,y
,width
和height
会变成奇怪的值(例如-1405737648
)
解决这些命名冲突的最佳方法是什么?
答案 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);
}
i
,int i=10
的最内层声明会隐藏i
语句中声明的变量for
,这反过来会影响在i
声明的变量i
函数范围,它反过来影响全局变量x
。
在手头的问题中,对{class 1}}的非默认构造函数的参数y
,width
,height
和A
会影响成员数据与这些参数的名称相同。
您的width=width;
没有做任何事情,因为参数width
遮蔽(隐藏)数据成员width
。当您有两个或多个具有相同名称且在不同范围内声明的变量时,获胜者始终是具有最内部范围的名称。通常,它始终是赢得最内层范围的名称。
答案 3 :(得分:2)
虽然您可以通过使用构造函数的初始化列表来避免此问题,但我建议遵循命名数据成员的约定,例如,尾随_
或前导m_
。否则,您很可能会发生名称冲突,特别是如果您的成员名称为x
和y
。
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;
}