I'm unexperienced with C++ coming from other OOP languages.
Looking for a way to initialize constant objects, let's say I have this simple vector:
Vector3D UP = Vector3D(0,1,0);
and I would like to reuse the object behind the UP
variable.
for example in Java you would make it a static field inside some class:
class Constants {
public static final Vector3D UP = new Vector3D(0,1,0);
}
and can access it like this:
Vector3D up = Constants.UP;
How, in C++, do I safely tell it to initialize that object once and then have it immutably accessible anywhere I include the header?
I've read that static initialization is potentially very bad in C++ because the compilation order is nondeterministic and if you're having dependencies between different constants you could end up with undefined initialization state if they're not in the same compilation unit.
If Vector3D
is a simple enough class, a literal type, for which you may define a constexpr
constructor, then the most straightforward way is likely to define it in a header as follows:
namespace Constants {
constexpr Vector3D UP(0,1,0);
}
This makes is a true compile time constant, so it will likely occupy no storage (depends on how you use it). If it does end up occupying storage, then the constexpr
specifier implies internal linkage. Every translation unit that needs the constant to have storage has its own copy of the constant. So you don't run afoul of the static initialization order fiasco (inside a single TU, declaration order of namespace scope static objects dictates initialization order).
Since C++17, those multiple definitions can be condensed into one with the help of the inline
specifier. The one true constant will look like this:
namespace Constants {
inline constexpr Vector3D UP(0,1,0);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With