我们最近在我的EECS课堂上讨论了这个主题。如果你想详细查看讲义,请访问http://umich.edu/~eecs381/lecture/IdiomsDesPattsCreational.pdf。这些笔记(以及我在这个回答中提供的引用)是由我的教授David Kieras创建的。
我知道两种正确创建Singleton类的方法。
第一种方法:
将其实现方式与您示例中的方式相似。至于销毁,“单例通常持续整个程序运行时间;大多数操作系统将在程序终止时恢复内存和其他大部分资源,因此有一个不用担心这个问题的方法。”
然而,在程序终止时清理是一个好的习惯。因此,您可以使用一个辅助的静态SingletonDestructor类,并在您的Singleton中声明它为友元。
class Singleton {
public:
static Singleton* get_instance();
Singleton(const Singleton&) = delete;
Singleton(Singleton&&) = delete;
Singleton& operator=(const Singleton&) = delete;
Singleton& operator=(Singleton&&) = delete;
friend class Singleton_destroyer;
private:
Singleton();
~Singleton();
static Singleton* ptr;
};
class Singleton_destroyer {
public:
~Singleton_destroyer { delete Singleton::ptr; }
};
Singleton_destoyer the_destroyer;
Singleton_destroyer将在程序启动时创建,当程序终止时,所有全局/静态对象都会被运行时库关闭代码(由链接器插入)销毁,因此destroyer将被销毁;它的析构函数将删除Singleton并运行其析构函数。
第二种方法
这被称为Meyers Singleton,是由C++巨匠Scott Meyers创建的。只需以不同的方式定义get_instance()即可。现在您还可以摆脱指针成员变量。
static Singleton& Singleton::get_instance()
{
static Singleton s;
return s;
}
这很方便,因为返回的值是引用,您可以使用 .
语法而不是 ->
来访问成员变量。
"编译器会自动构建代码,首次声明时创建's',之后不再创建,并在程序终止时删除静态对象。"
请注意,对于Meyers单例模式,如果对象在终止时相互依赖,则可能会遇到非常困难的情况-相对于其他对象,Singleton何时消失?但对于简单的应用程序,这很有效。