成员名称和构造函数参数名称之间的冲突
Conflicts between member names and constructor argument names
可能的重复:
成员与方法参数访问C++
我有一个类,它有一些成员,如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
)。
解决这些命名冲突的最佳方法是什么?
您可以使用具有相同名称的初始化列表:
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)
{
}
但第一个建议并没有错。
如果必须在构造函数中使用赋值(而不是使用首选初始值设定项列表),则解决此问题的特定模式是使用指针this
如下所示:
this->a = a;
如果可能的话,最好通过初始值设定项列表设置数据成员,在这种情况下,隐藏成员名称的参数没有问题。另一种选择是在构造函数的主体中使用this->foo = foo;
。资源库也存在类似的问题,但现在无法使用初始值设定项列表解决方案。你被困在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
,隐藏了在for
语句中声明的变量i
,而i
在函数作用域声明的变量又隐藏了全局变量i
。
在手头的问题上,参数x
、y
、width
和height
到类的非默认构造函数A
隐藏与这些参数同名的成员数据。
您的width=width;
没有执行任何操作,因为参数width
阴影(隐藏)数据成员width
。当您有两个或多个在不同作用域声明的具有相同名称的变量时,获胜者始终是作用域最内侧的名称。通常,始终是具有最内层范围的名称获胜。
尽管您可以通过使用构造函数的初始化列表来避免此问题,但我建议遵循命名数据成员的约定,例如尾随_
或前导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_;
};
您可以更改构造函数参数的名称。当你写的时候
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;
}
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 如何使 std::sort 在 std::swap 和我的命名空间的模板化交换之间没有名称冲突?
- 库之间的冲突
- 如何避免 Cocos2d-x 3.15.1 中的 MenuItemImage 和 MenuItemSprite 之间的冲突
- 包括两个文件 C++ 之间的冲突
- 如何解决两个不使用命名空间的第三方库之间的类名冲突?
- 2 个 QGraphicsPixmapItems 之间的 QT 冲突检测
- 字符串和整数之间的模板冲突
- 两个提升版本之间的冲突
- C++编译错误是由于使用 std::move 时运动构造函数与其他非运动构造函数之间的冲突
- 调用 ADL 时,表达式和命名空间之间是否会发生冲突
- 复制构造函数和模板构造函数之间的冲突
- 名称名称空间和类模板之间的冲突:不同的编译器行为
- 如何解决GMP的32位和64位库之间的冲突
- OpenCV和Tesseract之间是否存在任何冲突
- 最新版本的提升和提升几何库 (GGL) 之间的冲突
- 包含:stdafx.h 和 <vector> VisualStudio 2012 C++ 之间的冲突(错误 C2953:已定义类模板)
- 类名和枚举值之间的冲突:无需命名空间即可解析
- C Socket 和 Omnet++ 之间的方法名称冲突
- 在类层次结构中,完美的转发构造函数和复制构造函数之间的冲突