c++ - 不初始化 C++ 构造函数中的每个成员是一种好习惯吗?

标签 c++ oop

我有一个有两种状态的类,不同的成员只适用于一种状态或另一种状态。

哪个是更好的做法:

  • 选项 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/

相关文章:

c++ - 从 iterator.first 获取值

c++ - Boost.Serialization 会直接与虚拟菱形继承(钻石问题)一起工作吗?

python - python中的类继承

api - 抽象正在使用的 API 是一种好习惯吗?

Python:递归isinstance检查

c++ - 如何在 C++ 中异步处理 native 套接字上的 https 请求响应

c++ - 代码输出随机符号,我不确定出了什么问题

多态性的 C++ 问题 - 数据被覆盖

python - Python中的继承和内部类?

c++ - 如何交叉编译 arm video for linux 和 udev