单例模式
概念
单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。
GoF对单例模式的定义是:保证一个类、只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。
为什么使用单例模式
在应用系统开发中,我们常常有以下需求:
- 在多个线程之间,比如初始化一次socket资源;比如servlet环境,共享同一个资源或者操作同一个对象
- 在整个程序空间使用全局变量,共享资源
- 大规模系统中,为了性能的考虑,需要节省对象的创建时间等等。
因为Singleton模式可以保证为一个类只生成唯一的实例对象,所以这些情况,Singleton模式就派上用场了。
实现单例步骤常用步骤
1、构造函数私有化
2、提供一个全局的静态方法(全局访问点)
3、在类中定义一个静态指针,指向本类的变量的静态变量指针
简单案例:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
/*单例模式
*分为 懒汉式 和 饿汉式
*/
//懒汉式
class Singleton_lazy{
private:
Singleton_lazy(){
cout << "我是懒汉式构造!!!" << endl;
}
public:
static Singleton_lazy* getInstance(){
if (single == NULL){
single = new Singleton_lazy;
}
return single;
}
private:
static Singleton_lazy* single;
};
//静态数据类外初始化
Singleton_lazy* Singleton_lazy::single = NULL;
//饿汉式
class Singleton_hungry{
private:
Singleton_hungry(){
cout << "我是饿汉式构造!!!" << endl;
}
public:
static Singleton_hungry* getInstance(){
return hungry;
}
private:
static Singleton_hungry* hungry;
};
Singleton_hungry* Singleton_hungry::hungry = new Singleton_hungry;
int main(void){
cout << "主函数开始执行" << endl;
return 0;
}
单例模式中对象的释放:
在单例模式中,因为每个类只涉及一个对象,所以不需要刻意释放,在程序结束后会自动释放。
多线程下的懒汉式单例和饿汉式单例
1、懒汉"模式虽然有优点,但是每次调用GetInstance()静态方法时,必须判断 NULL == m_instance,使程序相对开销增大。
2、多线程中会导致多个实例的产生,从而导致运行代码不正确以及内存的泄露。
3、提供释放资源的函数
单例模式遇到多线程,懒汉模式是线程不安全的,饿汉模式是线程安全的
因此:多线程中若需要使用单例模式,最好使用饿汉模式。