I have a class which shall have member fields of itself, like this:
class T {
static T a;
static T b;
static T c;
};
I want to avoid the static initialization order fiasco, so I changed them into static getters:
class T {
static T A();
static T B();
static T C();
};
T T::A() { // B() and C() are implemented analogously.
static T const a;
return a;
}
Now, each instance of T
shall have a constant copy of another instance of T
. For example A
could have a reference to B
and vice versa. I would like to pass this reference in the constructor, but then, during construction of A()
, B()
would be called, calling A()
again, but A
's object is already under construction and therefore cannot return a copy. I'd solve this like this:
class T {
static T A();
static T B();
static T C();
// t not settable on construction
//T const t;
//T (T const & t) : t(t) { }
T t;
};
T T::A() { // B() and C() are implemented analogously.
static T const a;
static bool b_once{true};
if (b_once) {
b_once = false;
a.t = B();
}
return a;
}
If feel like this is a lot of effort and probably not the best solution. Is there a better way?
Additional information
I want A()
, B()
and C()
to be implemented in different translation-units, hence my worries about the static initialization order fiasco.
T
cannot have a member of type T
.
(because if it would then that member would have another member of type T
with another member of type T
with another member of type T
.... a T
is never not a T
.)
T
can have a member of type T*
. You can take the adress of the static members before they are initialized:
class T {
static T A;
static T B;
static T C;
T* t;
T(T* t) : t(t) {}
};
T T::A = T{&T::B};
T T::B = T{&T::C};
T T::C = T{&T::A};
The initialization of those three does not really depend on each other. Only by the time you dereference the pointer, the pointee must be alive.
Even if it would, as mentioned in a comment, the order of initialization within one translation unit is well defined.