如何最好地初始化和存储常量对象?

时间:2019-07-11 09:16:40

标签: c++

我对其他OOP语言的C ++经验不足。

寻找一种初始化常量对象的方法,假设我有一个简单的向量:

Vector3D UP = Vector3D(0,1,0);

,我想重用UP变量后面的对象。

例如在Java中,您可以将其设置为某个类内的静态字段:

class Constants {
  public static final Vector3D UP = new Vector3D(0,1,0);
}

并可以这样访问它:

Vector3D up = Constants.UP;

在C ++中,如何安全地告诉它一次初始化该对象,然后在包含标头的任何地方使它不变地访问?

我已经读到静态初始化在C ++中可能非常糟糕,因为编译顺序是不确定的,并且如果您在不同常量之间具有依赖关系,则如果它们不在同一编译单元中,则可能会出现未定义的初始化状态

1 个答案:

答案 0 :(得分:7)

如果Vector3D是一个非常简单的类,literal type,您可以为其定义一个constexpr constructor,则最直接的方法可能是在标头中对其进行定义,如下所示:

namespace Constants {
  constexpr Vector3D UP(0,1,0);
}

这是一个真正的编译时间常数,因此它很可能不占用任何存储空间(取决于您的使用方式)。如果它确实占用了存储空间,则constexpr说明符表示内部链接。每个需要常量存储的转换单元都有自己的常量副本。因此,您不会遇到静态初始化顺序失败的麻烦(在单个TU中,名称空间范围静态对象的声明顺序决定了初始化顺序)。

从C ++ 17开始,可以在inline specifier的帮助下将这些多个定义浓缩为一个。一个真实的常数将如下所示:

namespace Constants {
  inline constexpr Vector3D UP(0,1,0);
}