我有一个有两种状态的类,不同的成员只适用于一种状态或另一种状态。
哪个是更好的做法:
- 选项 1:构造函数仅初始化与第一个(初始)状态相关的成员
- 选项 2:初始化每个成员,即使这意味着为成员发明“未初始化”的值?
例如
class Foo {
public:
enum State { A, B };
// Constructor
// Option 1: Only initialize first state
Foo(int a1) : _state(A), _a1(a1) {}
// ... or ...
// Option 2: initialize every member
Foo(int a1) : _state(A), _a1(a1), b1(-1), b2(-1) {}
State getState() const { return _state; }
// Only applicable if State is A
int getA1() const { return _a1; } // Might also add assert that State is A
// Only applicable if State is B
int getB1() const { return _b1; } // Might also add assert that State is B
int getB2() const { return _b2; } // Might also add assert that State is B
private:
State _state;
int _a1;
int _b1;
int _b2;
};
最佳答案
从未初始化的变量中读取是未定义的行为,因此如果您使用选项 1 然后有人调用 getB1()
或 getB2()
,你有未定义的行为。
选项 1 本身没有任何问题只要您清楚地记录调用这些 getter 可能会调用未定义的行为以及在什么情况下会发生这种情况。通过这种方式,您可以将确保已定义行为的负担转移给此类的使用者。
您还可以存储指示它们是否已被初始化的标志,如果在它们被初始化之前尝试读取则抛出异常。这样你会得到一个明确定义的错误而不是 UB。 (您也可以在这里使用 boost::optional<int>
,它负责为您提供这个额外的标志。)
考虑到所有这些要点,使用“虚拟”值可能更可取,因为不存在未定义行为的风险并导致更简单的实现。 (如果您确实使用了虚拟值,请确保提供静态常量值,以便调用者可以比较该值是否未设置。)
关于c++ - 不初始化 C++ 构造函数中的每个成员是一种好习惯吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28156756/