Ano*_*non 24 c++ singleton design-patterns
编辑:对不起,我的问题不明确,为什么书籍/文章更喜欢实施#1而不是实施#2?
使用指针实现Singleton类与使用静态对象的实际优势是什么?为什么大多数书都喜欢这个
class Singleton
{
private:
static Singleton *p_inst;
Singleton();
public:
static Singleton * instance()
{
if (!p_inst)
{
p_inst = new Singleton();
}
return p_inst;
}
};
Run Code Online (Sandbox Code Playgroud)
在此
class Singleton
{
public:
static Singleton& Instance()
{
static Singleton inst;
return inst;
}
protected:
Singleton(); // Prevent construction
Singleton(const Singleton&); // Prevent construction by copying
Singleton& operator=(const Singleton&); // Prevent assignment
~Singleton(); // Prevent unwanted destruction
};
Run Code Online (Sandbox Code Playgroud)
Mik*_*our 17
为什么书籍/文章更喜欢实施#1而不是实施#2?
因为大多数描述Singleton反模式的文章在尝试在C++中安全地实现它时并不完全理解所有隐藏的危险.做到这一点非常困难.
使用指针实现Singleton类与使用静态对象的实际优势是什么?
使用指针new但是没有delete,确保永远不会销毁该对象,因此在其生命周期结束后不存在访问它的危险.结合"懒惰"创建,第一次访问它,这保证了所有访问都是有效的对象.缺点是创建不是线程安全的,并且它获取的对象和任何资源不会在程序结束时释放.
使用本地静态对象,在任何支持C++ 11线程模型的编译器上创建都是线程安全的.此外,该对象将在程序结束时被销毁.但是,可以在破坏后访问对象(例如,从另一个静态对象的析构函数),这可能会导致令人讨厌的错误.
最好的选择是尽可能避免静态数据和全局可访问的数据.特别是,永远不要使用Singleton反模式; 它将全局静态数据与奇怪的实例化限制相结合,使得测试变得不必要.
第二个版本(使用本地静态变量)具有显着的优点.
它不需要使用免费存储,因此不会被检测为内存泄漏.它是线程安全的(in C++11).它更短更简单.
唯一的缺点是它不可能使其成为线程安全(对于前C++ 11编译器),并且它不会为您提供显式销毁单例实例的选项.
第二个示例被称为“Meyers' Singleton”,因为它首先在“Effective C++”或“More Effect C++”中发布。我不确定是哪一个,但两者都是在“设计模式”之后出版的 - 所以四人帮在写书时可能还没有意识到第二种模式。
此外,第一种方法对于其他语言来说更为标准 - 您可以使用 Java 或 C# 执行第一种方法,但不能使用第二种方法,因此来自不同背景的人可能是第一种方法更出名的另一个原因。
从技术角度来说,第一种方法可以控制单例何时被销毁,但这也会给你带来很多麻烦。