在 C++ 中初始化对象数组时出错
Posted
技术标签:
【中文标题】在 C++ 中初始化对象数组时出错【英文标题】:Error Initializing Object Array in C++ 【发布时间】:2015-06-03 07:21:14 【问题描述】:当我运行尝试初始化对象数组的代码时,其中一个对象的值无效,它似乎没有调用构造函数,它会设置适当的默认值。下面的代码产生输出:
1
2
1528112104
玩具代码:
#include <iostream>
using namespace std;
class BeeBoop
public:
static const int MIN_X = 1;
static const int MAX_X = 2;
BeeBoop(int x);
int getX() return x;
bool setX(int x);
private:
int x;
;
int main()
BeeBoop boops[] =
BeeBoop(1),
BeeBoop(2),
BeeBoop(3)
;
for (int i = 0; i < 3; i++)
cout << boops[i].getX() << endl;
BeeBoop::BeeBoop (int x)
if(!setX(x))
x = MIN_X;
bool BeeBoop::setX(int x)
if (x < MIN_X || x > MAX_X)
return false;
this->x = x;
return true;
为什么不调用构造函数并将其设置为 BeeBoop(3) 的默认值?
更奇怪的是,如果我将初始化列表的顺序切换为
...
BeeBoop boops[] =
BeeBoop(1),
BeeBoop(3),
BeeBoop(2)
)
...
输出变成:
1
0
2
所以它初始化为 0,这也不是默认值。
【问题讨论】:
第一个想法是你没有设置this->x
,而只是设置x
,因此this->x
永远不会被初始化。你能确认一下吗?
我不确定,但如果 x 已设置,您的“检查”可能是错误的吗? if(!setX(x))
的行为因x
的值而异,该值尚未初始化。所以从技术上讲,它可以有任何价值。如果你很幸运,它是0
,在这种情况下你的代码可以工作,但不一定是这样。
【参考方案1】:
您将名称x
用作函数参数和成员变量(可能不是一个好主意!)。因此你需要改变:
BeeBoop::BeeBoop (int x)
if(!setX(x))
x = MIN_X;
到:
BeeBoop::BeeBoop (int x)
if(!setX(x))
this->x = MIN_X;
否则你只是修改参数x
而不是设置成员变量。 (或者,您可以只为参数和成员变量使用唯一名称以避免这种歧义。)
请注意,如果您在编译时启用了适当的警告 (-Wshadow
),编译器将能够指出您的错误:
main.cpp: In constructor 'BeeBoop::BeeBoop(int)':
main.cpp:30:24: warning: declaration of 'x' shadows a member of 'BeeBoop' [-Wshadow]
BeeBoop::BeeBoop (int x)
^
main.cpp:14:13: note: shadowed declaration is here
int x;
^
main.cpp: In member function 'bool BeeBoop::setX(int)':
main.cpp:36:25: warning: declaration of 'x' shadows a member of 'BeeBoop' [-Wshadow]
bool BeeBoop::setX(int x)
^
main.cpp:14:13: note: shadowed declaration is here
int x;
【讨论】:
就是这样。太傻了。【参考方案2】:类成员函数的局部变量和函数参数是隐藏类的数据成员的局部变量。
例如在名为x
的构造函数参数中隐藏了数据成员x
BeeBoop::BeeBoop (int x)
if(!setX(x))
x = MIN_X;
因此在声明中
x = MIN_X;
在赋值的左侧有使用的参数x
。
你应该使用任何一个
BeeBoop::x = MIN_X;
或
this->x = MIN_X;
存在相同问题的所有函数都必须以相同的方式更新。
考虑到最好用qualofoer const
声明函数getX
int getX() const return x;
由于类的构造函数没有说明符explicit
,所以它是一个转换构造函数。这意味着你可以简单地写
BeeBoop boops[] = 1, 2, 3 ;
函数 main 可以通过以下方式简化:)
int main()
for ( BeeBoop b : 1, 2, 3 )
std::cout << b.getX() << std::endl;
程序输出将是
1
2
1
【讨论】:
以上是关于在 C++ 中初始化对象数组时出错的主要内容,如果未能解决你的问题,请参考以下文章