【发布时间】:2018-11-09 09:18:09
【问题描述】:
下面的代码说明了Andrey Alexandrescu's Modern C++ Design book 中描述的Phoenix Singleton。
Singleton& Instance()
{
if (!pInstance_)
{
// Check for dead reference
if (destroyed_)
{
OnDeadReference();
}
else
{
// First call—initialize
Create();
}
}
return pInstance_;
}
void Singleton::OnDeadReference()
{
// Obtain the shell of the destroyed singleton
Create();
// Now pInstance_ points to the "ashes" of the singleton
// - the raw memory that the singleton was seated in.
// Create a new singleton at that address
new(pInstance_) Singleton;
// Queue this new object's destruction
atexit(KillPhoenixSingleton);
// Reset destroyed_ because we're back in business
destroyed_ = false;
}
static void Create();
{
// Task: initialize pInstance_
static Singleton theInstance;
pInstance_ = &theInstance;
}
void Singleton::KillPhoenixSingleton()
{
// Make all ashes again
// - call the destructor by hand.
// It will set pInstance_ to zero and destroyed_ to true
pInstance_->~Singleton();
}
virtual ~Singleton()
{
pInstance_ = 0;
destroyed_ = true;
}
Singleton* Singleton::pInstance_ = 0;
bool Singleton::destroyed_ = false;
书中引用:
让我们分析一下事件的流程。在应用程序退出序列期间,Singleton 的析构函数被调用。 析构函数将指针重置为零并将destroyed_设置为true。现在假设一些全局对象 尝试再次访问 Singleton。实例调用 OnDeadReference。死引用 重新激活 Singleton 并将对 KillPhoenixSingleton 的调用排队,并且 Instance 成功 返回对有效 Singleton 对象的引用。从现在开始,这个循环可能会重复。
我的问题是 - 如果我们在析构函数中分配给指针pInstance_ = 0,而不是分配给应该在此时删除的本地静态引用,我们如何将新对象放置在 0 地址?请告诉我我遗漏了一些东西。如果有人可以向我解释流程,我将不胜感激。谢谢
【问题讨论】:
-
pInstance_声明在哪里? -
在底部,向下滚动,它是一个静态指针成员