Tob*_*ias 4 c++ destructor initialization-order static-initialization
有一个简单且众所周知的模式可以避免静态初始化失败,在C++ FAQ Lite 的第 10.13 节中进行了描述。
在这个标准模式中,有一个权衡是构造的对象永远不会被破坏(如果析构函数没有重要的副作用,这不是问题)或者不能从另一个静态对象的析构函数安全地访问静态对象(请参阅C++ FAQ Lite 的 10.14 节)。
所以我的问题是:如果静态对象的析构函数具有最终必须发生的重要副作用并且静态对象必须由另一个静态对象的析构函数访问,那么您如何避免静态反初始化失败?
(注意:FAQ-lite 提到这个问题在C++ FAQs: FAQs 16.17 of C++ FAQs: FAQs by M. Cline and and and G. Lomow 中得到了回答。我无权阅读这本书,这就是我问这个问题的原因。 )
函数静态对象(如全局对象)保证会被销毁(假设它们已创建)。
毁灭的顺序是创造的逆序。
因此,如果一个对象在销毁期间依赖于另一个对象,您必须保证它仍然可用。这相对简单,因为您可以通过确保正确完成创建顺序来强制销毁顺序。
以下链接是关于单例的,但描述了类似的情况及其解决方案:
寻找 C++ 静态初始化顺序问题
推断到 FAQ lite 中描述的惰性初始化全局变量的一般情况,我们可以解决这样的问题:
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;
}
}
Run Code Online (Sandbox Code Playgroud)