单例模式是一个创建型设计模式,一个类只会创建一个对象。
由于只有一个对象,所以不能够通过new来创建对象,因此类的构造函数得是private的
由于不能够new出对象,所以类内部需要提供一个函数来获取对象,这个函数和对象都是属于类的,而不是对象,因此这个函数和唯一 的对象都得是static的,并且对象是private类型的,函数是public类型的
1. 构造函数私有化,避免外部使用构造函数来创建对象
2. 增加静态私有的当前类的指针变量
3. 提供静态的public接口,可以让用户获取单例
一个类只需要一个对象实例

优点:
第一次调用的时候才初始化,避免内存浪费
缺点:
必须加锁才能够保证单例,加锁会影响效率
实例:
class SingletonLazy{
private:
SingletonLazy(){
std::cout << "single lazy!" << std::endl;
}
public:
static SingletonLazy* getInstatce(){
if( NULL == lazy ){
lazy = new SingletonLazy;
}
return lazy;
}
private:
static SingletonLazy* lazy;
};
//类外初始化
SingletonLazy* SingletonLazy::lazy = NULL;
优点:
不需要加锁,执行效率高,线程安全的
缺点:
不管是不是用都会初始化,浪费内存
实例:
class SingletonHungry{
private:
SingletonHungry(){
std::cout << "single hungry!" << std::endl;
}
public:
static SingletonHungry* getInstatce(){
return hungry;
}
//SingletonHungry类退出以后会自动析构free_single,
//从而调用FreeSingle的析构函数来释放单例
//其实类退出时会自动释放单例不需要该类
class FreeSingle{
~FreeSingle(){
if( NULL != hungry ){
delete hungry;
hungry = NULL;
}
}
};
private:
static SingletonHungry* hungry;
static FreeSingle free_single;
};
//类外初始化
SingletonHungry* SingletonHungry::hungry = new SingletonHungry;
// 局部静态变量
class Singleton{
public:
// 使用指针而不是引用是为了避免拷贝构造函数进行拷贝
// Singleton single = Singleton::getInstance();
static Singleton* getInstance(){
static Singleton instance;
return &instance;
}
private:
Singleton(){
std::cout << "局部静态方式" << std::endl;
}
// 如果需要getInstance 返回引用,
// 也可以通过重载赋值运算符和拷贝构造函数,这两个函数不需要具体的实现
Singleton(Singleton const & single);
Singleton& operator = (const Singleton& single);
};
class SingletonMulThread{
private:
SingletonMulThread(){
std::cout << "single MulThread!" << std::endl;
}
public:
static SingletonMulThread* getInstatce(){
if( NULL == single_multhread ){
std::lock_guard<std::mutex> lock(mutex);
if( NULL == single_multhread ){
single_multhread = new SingletonMulThread;
}
}
return single_multhread;
}
private:
static SingletonMulThread* single_multhread;
static mutex mutex;
};
//类外初始化
SingletonMulThread* SingletonMulThread::single_multhread = NULL;
mutex SingletonMulThread::mutex;