迈尔·辛格尔顿的破坏顺序 [英] Destruction Order of Meyers Singletons
问题描述
转到以下代码:
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
我有几个问题:
- 销毁电话的顺序是否已明确定义? (即使C和D类在不同的源文件中定义)
- 如果定义明确,这种行为是否可以移植?
推荐答案
此构造的目的是施加构造顺序(因此也施加破坏顺序).
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屋!