饿汉模式:线程安全
懒汉模式:非线程安全
#include <iostream>
using namespace std;
class Singleton
{
private:
Singleton()
{}
Singleton(const Singleton&); //禁止访问拷贝构造函数
Singleton& operator = (const Singleton&); //禁止使用操作符=
static Singleton* p;
class DeleteTool //内部类,专门用于在析构的时候删除p
{
public:
~DeleteTool()
{
if (Singleton::p)
{
delete p;
cout << "delete p" << endl;
}
}
};
static DeleteTool deleteTool; //内部类,不能用指针的形式,以为用指针析构的时候不会释放指针指向的对象
public:
static Singleton* getInstance();
//Singleton(const Singleton&) = delete; // = delete的作用是让编译器不为其声称拷贝构造函数,作用类似于上面的将拷贝构造函数声明为私有
//Singleton& operator = (const Singleton&) = delete; //同上
};
Singleton::DeleteTool Singleton::deleteTool; //对内部类进行定义,不定义的话退出的时候不会调用析构函数。
//饿汉模式,线程安全
Singleton* Singleton::p = new Singleton();
Singleton* Singleton::getInstance()
{
return p;
}
//懒汉模式,线程不安全
//Singleton* Singleton::p = NULL; //饿汉模式,线程安全
//Singleton* Singleton::getInstance()
//{
// if (p == NULL)
// p = new Singleton();
// return p;
//}
int main()
{
Singleton* a = Singleton::getInstance();
//Singleton b(*a); //报错,拷贝构造函数无法被访问
//Singleton c = *a; //报错,运算符=无法被访问
return 0;
}
更新:
用static来代替new,这样既是懒汉,又是线程安全的
来源http://stackoverflow.com/questions/1008019/c-singleton-design-pattern
class S
{
public:
static S& getInstance()
{
static S instance; // Guaranteed to be destroyed.
// Instantiated on first use.
return instance;
}
private:
S() {} // Constructor? (the {} brackets) are needed here.
// C++ 03
// ========
// Dont forget to declare these two. You want to make sure they
// are unacceptable otherwise you may accidentally get copies of
// your singleton appearing.
S(S const&); // Don't Implement
void operator=(S const&); // Don't implement
// C++ 11
// =======
// We can use the better technique of deleting the methods
// we don't want.
public:
S(S const&) = delete;
void operator=(S const&) = delete;
// Note: Scott Meyers mentions in his Effective Modern
// C++ book, that deleted functions should generally
// be public as it results in better error messages
// due to the compilers behavior to check accessibility
// before deleted status
};