gpt4 book ai didi

c++ - 陷阱 : The static stack variable Singleton class

转载 作者:太空狗 更新时间:2023-10-29 20:14:47 26 4
gpt4 key购买 nike

我已经有一些使用指针的单例类:

class Logger
{
public:

static Logger* Instance()
{
if (!m_pInstance) m_pInstance = new Logger;
return m_pInstance;
}
private:
Logger();
Logger(Logger const&);
Logger& operator=(Logger const&);
static Logger* m_pInstance;
};

但是,有一个更简单的方法,使用引用:

class Logger
{
public:
static Logger& Instance()
{
static Logger theLogger;
return theLogger;
}
private:
Logger();
Logger(Logger const&);
Logger& operator=(Logger const&);
~Logger();
};

阅读文章 C++ Singleton design pattern ,它警告第二种方式:

[Potential Pitfall]: This form of the singleton can present a problem because of the life expectancy of the object. If one singleton is instantiated within another, one must be keenly aware of the destructor call sequence.

但我不明白,谁能告诉我它的错误用法,我应该避免它?

最佳答案

确实,这两种选择都存在问题。

典型的单例

class Logger
{
public:

static Logger* Instance()
{
if (!m_pInstance) m_pInstance = new Logger;
return m_pInstance;
}
private:
Logger();
Logger(Logger const&);
Logger& operator=(Logger const&);
static Logger* m_pInstance;
};

此代码不是线程安全的,因此对new Logger 的调用可能会发生多次(在不同的线程中)。它还会泄漏 Logger 实例(因为它永远不会被删除),如果应该执行析构函数,这可能是个问题。

Meyer 的单例

class Logger
{
public:
static Logger& Instance()
{
static Logger theLogger;
return theLogger;
}
private:
Logger();
Logger(Logger const&);
Logger& operator=(Logger const&);
~Logger();
};

Meyer 的 Singleton 的问题确实是由于对象的破坏。在您从 main 返回后,所有全局变量的析构函数将按照与构造这些全局变量 1 时相反的顺序运行。这就好像那些全局变量是在堆栈上构建的。

如果一个对象是在您的 Logger 之前构造的,并试图在它自己的析构函数中使用它;那么它将使用一个已经被破坏的对象,导致未定义的行为。

1 更准确地说,按照构造函数完成的相反顺序。


最简单的替代方法是重新访问典型的单例:

class Logger {
public:
static Logger& Instance() {
static Logger* L = new Logger;
return *L;
}
private:
...
};

这现在是线程安全的,但仍然存在泄漏。但实际上泄漏在这里是需要的,因为它保证这个对象比任何其他将调用其析构函数的对象保持存活的时间更长。 警告:如果您曾在析构函数中执行某些操作,它将永远不会运行。

还有其他变体,例如 Alexandrescu 的 Phoenix Singleton,如果您在死后需要它,它会从 Ember 中复活;然而,在销毁期间同时获得线程安全安全行为是很难实现的。

关于c++ - 陷阱 : The static stack variable Singleton class,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15312264/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com