How to perform static deinitialization if the destructor has side effects and another destructor of the static object is accessing the object?

There is a simple and well-known template to avoid the static initialization debacle described in section 10.13 of the C ++ FAQ Lite .

There is a trade-off in this standard template in that either the constructed object is never destroyed (which is not a problem if the destructor has no important side effects), or the static object cannot be safely accessed from another static destructor object (see Section 10.14 C ++ FAQ Lite ).

So my question is: how do you avoid a static deionization fiasco if a static destructor object has important side effects that should ultimately happen and another static destructor object should be addressed to the static object?


<sub> (Note: in FAQ-lite it is mentioned that this question answers in FAQ 16.17 of C ++ frequently asked questions: M. Kline and G. Lomov frequently asked questions. I do not have access to this book, so I ask this question.) sub>

+4
source share
3 answers

The function of static objects, such as global objects, will be guaranteed to be destroyed (provided that they are created).

The order of destruction is the reverse of yours.
Thus, if an object depends on another object during destruction, you must guarantee its availability. This is relatively simple, as you can force the order of destruction by making sure that the order of creation is done correctly.

The following link is about solid colors, but describes a similar situation and its solution:
Search for static C ++ initialization tasks

By extrapolating to the general case of lazy initialized globals, as described in the FAQ lite, we can solve the problem as follows:

namespace B { class B { ... }; B& getInstance_Bglob; { static B instance_Bglob; return instance_Bglob;; } B::~B() { A::getInstance_abc().doSomthing(); // The object abc is accessed from the destructor. // Potential problem. // You must guarantee that abc is destroyed after this object. // To gurantee this you must make sure it is constructed first. // To do this just access the object from the constructor. } B::B() { A::getInstance_abc(); // abc is now fully constructed. // This means it was constructed before this object. // This means it will be destroyed after this object. // This means it is safe to use from the destructor. } } namespace A { class A { ... }; A& getInstance_abc() { static A instance_abc; return instance_abc; } } 
+4
source

While the static destructor of another object is running, you're fine. You can assure this if another object is created before "object A". As long as both objects are declared in the same compilation unit, they will be initialized in the order they appear in the source and will be destroyed in the reverse order.

If you need this to happen in all compilation units, you're out of luck. It is better to create them dynamically at runtime and destroy them at the end of the main, rather than making them static.

0
source

This is a bit of a hack, but I would add some static bools to keep track of the initialization order. Then the object that ends last clears, even if it is not the owner.

0
source

Source: https://habr.com/ru/post/1314232/


All Articles