我对来自其他OOP语言的C ++经验不足。
寻找一种初始化常量对象的方法,假设我有一个简单的向量:
Vector3D UP = Vector3D(0,1,0);
Run Code Online (Sandbox Code Playgroud)
我想重用UP变量后面的对象。
例如在Java中,您可以将其设置为某个类中的静态字段:
class Constants {
public static final Vector3D UP = new Vector3D(0,1,0);
}
Run Code Online (Sandbox Code Playgroud)
并可以像这样访问它:
Vector3D up = Constants.UP;
Run Code Online (Sandbox Code Playgroud)
在C ++中,如何安全地告诉它一次初始化该对象,然后在包含标头的任何地方使它不变地访问呢?
我已经读到静态初始化在C ++中可能非常糟糕,因为编译顺序是不确定的,并且如果您在不同常量之间具有依赖关系,则如果它们不在同一编译单元中,则可能会出现未定义的初始化状态。
如果Vector3D是足够简单的类(即文字类型),可以为其定义constexpr构造函数,则最直接的方法可能是在标头中定义它,如下所示:
namespace Constants {
constexpr Vector3D UP(0,1,0);
}
Run Code Online (Sandbox Code Playgroud)
这是一个真正的编译时间常数,因此它很可能不会占用任何存储空间(取决于您如何使用它)。如果最终确实占用了存储空间,则说明constexpr符意味着内部链接。每个需要常量存储的转换单元都有自己的常量副本。因此,您不会违反静态初始化顺序的失败(在单个TU中,名称空间范围静态对象的声明顺序将指示初始化顺序)。
从C ++ 17开始,可以在inlinespecifier的帮助下将这些多个定义浓缩为一个。一个真正的常数将如下所示:
namespace Constants {
inline constexpr Vector3D UP(0,1,0);
}
Run Code Online (Sandbox Code Playgroud)