一,单例模式要解决的问题:
为了节省资源,使得一个类只能实例化唯一的一个对象;
二,单例模式的实现方式:
将生成对象的接口(构造函数和拷贝构造函数)屏蔽起来,然后在给出一个唯一的静态接口在类外进行实例化。
三,单例模式的分类:
1,懒汉(慢加载模式):在第一次用到类实例的时候才会去实例化。与之对应的是饿汉式单例。(懒汉本身是线程不安全的)
懒汉模式代码如下:
#include<iostream>
#include<thread>
using namespace std;
class Singleton {
private:
Singleton() {}
static Singleton* single;
public:
static Singleton* GetSingelton();
};
Singleton* Singleton::single = NULL;
Singleton* Singleton::GetSingelton()
{
if (single == NULL)
{
single = new Singleton;
}
return single;
}
int main()
{
Singleton* s1 = Singleton::GetSingelton();
Singleton* s2 = Singleton::GetSingelton();
if (s1 == s2)
{
cout << "s1 == s2" << endl;
}
else
{
cout << "s1 != s2" << endl;
}
return 0;
}
线程安全的懒汉模式代码如下:
//线程安全的懒汉单例模式(加锁解锁部分为伪代码,需要设置相应的加锁解锁行为)
class singleton
{
protected:
singleton() {}
private:
static singleton* p;
public:
static singleton* initance();
};
singleton* singleton::p = NULL;
singleton* singleton::initance()
{
if (p == NULL)
{
// 加锁
if (p == NULL)
p = new singleton();
//解锁
}
return p;
}
2,饿汉(快加载模式):在单例类定义的时候就进行实例化。(本身是线程安全的)
饿汉模式代码如下:
//饿汉单例模式
#include <iostream>
#include <process.h>
#include <windows.h>
class Singleton {
private:
Singleton(){}
static Singleton* single;
public:
static Singleton* GetSingleton();
};
// 饿汉模式的关键:初始化即实例化
Singleton* Singleton::single = new Singleton;
Singleton* Singleton::GetSingleton() {
// 不再需要进行实例化
return single;
}
四,关于如何选择懒汉和饿汉模式:
特点与选择:
懒汉:在访问量较小时,采用懒汉实现。这是以时间换空间。
饿汉:由于要进行线程同步,所以在访问量比较大,或者可能访问的线程比较多时,采用饿汉实现,可以实现更好的性能。这是以空间换时间。