最近得到Code Review的反馈说明了非初始化变量的不正确性,我的类变量初始化现在看起来非常难看:
class MyClass
{
private:
int variable_one;
int variable_two;
int variable_three;
MyClass():variable_one(0),variable_two(0),variable_three(0){};
//...
};
以前,我不会在需要之前定义我的变量:
class MyClass
{
private:
int variable_one;
void MyFunction(int x)
{
variable_one = x;
}
};
为什么我的第二个例子不赞成?机器人初始化变量涉及哪些风险?
答案 0 :(得分:3)
将变量保留为未初始化的风险是您可能在设置之前阅读它们。这可能导致极难诊断的错误和不稳定的行为。您还可以将它们初始化为哨兵值,以便更容易检测它们何时尚未设置。
作为一个注释,自从C ++ 11(现在大多数编译器都支持),你可以这样做:
class MyClass
{
private:
int variable_one = 0;
int variable_two = 0;
int variable_three = 0;
};
现在代码开销很少,并且明确表示它们会获得默认值,除非您专门将它们设置为其他内容。
答案 1 :(得分:2)
令人不悦的是因为某人有一天会使用你的类并假设在初始化期间已经设置了内部状态。您可能担心不需要初始化并浪费时间?相反,根据您拥有的各种各样和各种方法,您将在每个方法中重复初始化代码,直到您忘记其中一个,但它工作正常,因为您在调试模式下运行所以所有内存都被清除。然后一个月后,有人在发布时进行编译,突然他们认为他们的代码被破坏了,因为你没有在中心位置初始化你的代码。
RAII - 资源分配尽可能初始化。当他们创建一个类的实例时,请确保它已初始化。
答案 2 :(得分:2)
到目前为止提供的答案都是正确的,但没有人提到有更普遍的OO原则在起作用:对象的方法将其从一个内部一致状态转换为另一个。永远不可能使用一个对象做傻事(除非它是一个愚蠢的对象)。
例如,如果一个对象有一个数组和一个数组中当前活动的元素,那么当count为零时,永远不应该有活动元素。更新阵列的方法也会更新计数,使状态保持一致。在添加元素之后和更新计数之前,瞬间不一致对象的用户是不可见的。
在你的例子中,MyClass
通过创建一个非确定性的初始状态而走错了路。无论成员变量彼此之间有什么关系,它们的值都由编译器偶然事件决定。它使用的越多,你想要的概率就接近零。
答案 3 :(得分:1)
您指定的第一个方法称为初始化列表,这是在类中引用或引用数据成员时初始化的唯一方法。
如果不初始化作为C ++对象的数据成员,它仍将通过调用相应的构造函数初始化为默认值,然后当您尝试在以后初始化时,将重复相同的练习(就像你在一个函数中做的那样,当你认为有必要时)。