迈尔·辛格尔顿的破坏顺序 [英] Destruction Order of Meyers Singletons

查看:90
本文介绍了迈尔·辛格尔顿的破坏顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

转到以下代码:

class C {
public:    
    static C& Instance() {
       static C c;
       return c;
    }

   ~C(){std::cout << "c destructed\n";}
private:
   C(){}
};

class D{//similar to C but prints `d destructed` on destruction
//...

int main()
{
    auto c = C::Instance();
    auto d = D::Instance();
}
//outputs (with gcc)
//d destructed
//c destructed
//d destructed
//c destructed

我有几个问题:

  1. 销毁电话的顺序是否已明确定义? (即使C和D类在不同的源文件中定义)
  2. 如果定义明确,这种行为是否可以移植?

推荐答案

此构造的目的是施加构造顺序(因此也施加破坏顺序).

The point of this construct is to impose a construction order (and thus a destruction order).

建筑

由于它们是局部静态变量,因此构造顺序由首次调用它们各自的Instance函数的顺序确定.

Since these are local static variables, the order of construction is determined by the order in which their respective Instance functions are called for the first time.

由于是在main中完成的,因此完全指定了构造顺序.

Since that is done in main, the construction order is fully specified.

取消指定顺序的唯一方法是在不同翻译单元的静态初始化中使用它们,例如,如果有的话

The only way to make the order unspecified is if you use them in static initialisation in different translation units, for instance if one has

C& the_c = C::Instance();

而另一个拥有

D& the_d = D::Instance();

破坏

使用静态存储销毁对象与构造顺序相反.

The destruction of objects with static storage is the reverse of the order of construction.

3.6.3,终止,第1段:

3.6.3, Termination, paragraph 1:

如果构造函数完成或动态初始化 具有静态存储持续时间的对象的先于 另一个,第二个的析构函数的完成是有序的 在第一个的析构函数启动之前.

If the completion of the constructor or dynamic initialization of an object with static storage duration is sequenced before that of another, the completion of the destructor of the second is sequenced before the initiation of the destructor of the first.

因此,销毁顺序由施工顺序完全指定.

So the destruction order is fully specified by the construction order.

请注意,即使其中一个依赖于另一个,而不管翻译单位如何,也可以很好地指定此单例构造.

Note that this singleton construct is well specified even if one of them depends on the other, regardless of translation unit.

也就是说,这是绝对安全的,它的定义无关紧要:

That is, this is perfectly safe, and it doesn't matter where it's defined:

class C {
public:    
    static C& Instance() {
       static C c(D::Instance());
       return c;
    }

   ~C(){ m_d.doSomething(); } // Yes, this is safe.
private:
   C(D& d) : m_d(d) { m_d.doSomething(); } // Yes, this is safe.
   D& m_d;
};

这篇关于迈尔·辛格尔顿的破坏顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆