The point of this construction is the superposition of the construction order (and, therefore, the order of destruction).
Construction
Since these are local static variables, the construction order is determined by the order in which their respective Instance
functions are called for the first time.
Since this is done in main
, the construction order is fully specified.
The only way to make an order unspecified is to use it in static initialization in different translation units, for example, if you have
C& the_c = C::Instance();
and the other has
D& the_d = D::Instance();
Destruction
Destroying objects with static storage is the reverse of the build order.
3.6.3, Termination, paragraph 1:
If the completion of the constructor or dynamic initialization of an object with a static storage duration is sequenced to another, the completion of the destructor of the second is sequenced before the start of the destructor of the first.
Thus, the order of destruction is completely determined by the order of construction.
Note that this syntax construct is well indicated, even if one of them depends on the other, regardless of the unit of translation.
That is, it is completely safe, and it does not matter where it is defined:
class C { public: static C& Instance() { static C c(D::Instance()); return c; } ~C(){ m_d.doSomething(); }