C++ 尝试初始化构造函数中的数据成员,但失败。为什么?
结构指针的成员变量返回了错误的数字 以下是结构声明:C++ 尝试初始化构造函数中的数据成员,但失败。为什么?,c++,struct,instance-variables,C++,Struct,Instance Variables,结构指针的成员变量返回了错误的数字 以下是结构声明: struct Obj { int val; Obj(int val) { val = val; } }; 这里是它变得时髦的地方: Obj* cool = new Obj(4); cout << cool->val; // outputs a number that's not 4 cout << (cool->val == 4); // prints 0... interesting
struct Obj {
int val;
Obj(int val) { val = val; }
};
这里是它变得时髦的地方:
Obj* cool = new Obj(4);
cout << cool->val; // outputs a number that's not 4
cout << (cool->val == 4); // prints 0... interesting
这:
只是将参数赋值给自身,而将成员变量保留为包含垃圾。你需要:
Obj(int val) : val(val) {}
或者如果您确实需要分配而不是初始化:
Obj(int val) { this->val = val; }
或:
您可能想考虑对成员使用命名约定:
int m_val;
Obj(int val) : m_val(val) {}
为什么我会得到这些奇怪的数字?
您永远不会初始化Obj::val,因此该值正好是在构造Obj实例时该内存位置上的值
原因:这些名字在玩捉迷藏
在Obj的构造函数中,名为val的参数隐藏名为val的数据成员;换句话说,您正在将名为val的参数的值赋给名为val的参数
该标准说,在比以前声明更窄的范围内声明的变量将有效地隐藏旧的
这意味着,由于B处的参数val比a处的范围更窄,因此在C处,编译器认为您引用的是该参数
提议的解决办法
您有几种解决此问题的方法
this->val = val; // (A)
Obj::val = val; // equivalent
A、 使用此->val显式声明要将值分配给Obj的数据成员
B、 使用mem初始值设定项,其中Obj::val不会被参数名隐藏
C、 更改参数的名称
mem初始值设定项看起来很可怕,为什么包括它?
在建议的解决方案中,标有B的解决方案是首选方案
使用mem初始值设定项调用它,并在调用构造函数时直接使用参数val的值初始化成员val;而不是首先必须对其进行默认初始化,然后分配一个值
建议不要使用与成员变量同名的参数,因为如果忘记了名称隐藏,则很容易出错
一种常见的设计是在每个数据成员的前面加上m_,以明确表示该成员确实是实例的成员,如以下代码段中所示:
struct Obj {
Obj(int val) : m_val (val) { }
int m_val;
};
这->val=val。您可能应该在打开警告的情况下编译,他们会在心跳中指出这一点。实际上,cool应该是Obj cool4;。你看不到人们在做std::string*s=newstd::stringabc;每次他们需要一个对象时,至少我希望不是。cool->val==4是一个相等检查,因此是bool,如果为false,则为0,如果为true,则为1。正如您在前面的语句中所看到的,cool->val不是4,因此它打印0表示false。可能值得指出在构造函数中初始化数据成员的惯用方法。也就是说,您不会期望这里显示的任何形式是真实代码。我不同意您对解决方案B的偏好。解决方案C比B具有更少的歧义性。我从来没有对C有过任何问题,尤其是在代码审查中。@ThomasMatthews反问:如果数据成员不能,或者最好不应该,您将如何使用选项C,是我的错吗。我不同意B,因为参数名称与数据成员名称相同。我建议:Obj int val:m_valval{}。在我看来,这比保持相同的名称更具可读性。@ThomasMatthews当然,但选项的编写方式显示了所需的最小更改,不过,我将用一条语句更新帖子,说人们应该更愿意重命名数据成员。
struct Obj {
int val; // (A)
Obj(int val) { // (C)
val = val; // (B)
}
};
this->val = val; // (A)
Obj::val = val; // equivalent
Obj (int val) : val (val) { } // (B)
Obj (int foo) { val = foo; } // (C)
struct Obj {
Obj(int val) : m_val (val) { }
int m_val;
};