常用设计模式之单例模式
单例模式 (C++)
单例模式应该是很多项目里面经常会被使用到的一个设计模式,这里对单例模式的特点和写法做下介绍。
特点及应用
1. 特点
(1)故名思意,整个程序只会用到这么一个单例对象
举个例子:学校类比成一段程序,学校里面有一位校长对象,校长姓陈,校长今天被通知去教育局开会,明天要去教学生数学,后天要去小李老师课上听课,这三个事情就好比成三个方法,陈校长这个对象会在这三个方法中去做对应的事情,这个过程中一直都是陈校长在做,而不是李校长,王校长,张校长其他校长。
(2)需要通过一个全局访问方法来的得到这个单一实例
举个例子:还是以陈校长为例,陈校长是一个非常朴素的人,他没有手机,电脑等通讯工具,你只能通过去陈校长办公室这个方法来通知校长。
(3)懒汉单例和饿汉单例
懒汉单例:
这个类只有在第一次调用的时候才会被实例化对象。
饿汉单例:
这个类在程序启动或类被加载的时候,创建这个单例对象。
(4)构造函数为私有函数
以C++为例,构造函数的访问权限要求是Private
2. 解决了什么问题
避免一个全局使用的类对象频繁的创建和销毁,以及只使用仅有的这个单例对象,例如一些全局配置类。
3. 懒汉和饿汉的选择
如果一个单例类实例频繁被使用,建议使用饿汉,例如全局配置类,你需要频繁通过这个类去设置和取一些属性的时候;当一个单例类实例比较少被用到,甚至可能程序运行时,都不被用到的,选择懒汉。
写法介绍
懒汉单例
- 这个是C++11后出现的写法,这里的写法有两种,构造函数私有属性或者是构造函数共有属性删除
// 构造函数私有
class singleton
{
public:
static singleton* getInstance()
{
static singleton instance;
return &instance;
}
~singleton(){}
private:
singleton(){}
singleton(const singleton &value){}
singleton(singleton &&value){}
singleton &operator=(const singleton &value){}
singleton &operator=(singleton &&value){}
};
// 构造函数公有删除
class singleton
{
public:
static singleton* getInstance()
{
static singleton instance;
return &instance;
}
singleton(const singleton&) = delete;
singleton(singleton&&) = delete;
singleton& operator=(const singleton&) = delete;
singleton& operator=(singleton&&) = delete;
~singleton(){}
private:
singleton() = default;
};
- C++11前写法,使用互斥锁保证线程安全
// 构造锁类
#include <pthread.h>
class myLocker
{
public:
myLocker()
{
// 初始化互斥锁
if(pthread_mutex_init(&m_mutex, NULL) != 0)
{
throw std::exception();
}
}
~myLocker()
{
// 销毁互斥锁,释放内存
pthread_mutex_destroy(&m_mutex);
}
bool lock()
{
return pthread_mutex_lock(&m_mutex) == 0;
}
bool unlock()
{
return pthread_mutex_unlock(&m_mutex) == 0;
}
private:
pthread_mutex_t m_mutex;
};
class singleton
{
public:
static singleton* getInstance()
{
if (m_instance == NULL) // 解决并发问题,是否第一次调用
{
locker.lock();
if (m_instance == NULL) // 解决多线程时只能拥有一个单例问题
{
m_instance = new singleton();
}
locker.unlock();
}
return m_instance;
}
private:
singleton(){}
singleton(const singleton &value){}
singleton(singleton &&value){}
singleton& operator=(const singleton &value){}
singleton& operator=(singleton &&value){}
static singleton* m_instance;
myLocker locker;
};
singleton *singleton::m_instance = NULL;
myLocker singleton::locker;
懒汉单例
- 懒汉单例就简单多了
class singleton
{
public:
static singleton *getInstance()
{
return &instance;
}
private:
static singleton instance;
singleton() {}
singleton(const singleton &) = delete;
singleton &operator=(const singleton &) = delete;
singleton(singleton &&) = delete;
singleton &operator=(singleton &&) = delete;
};
singleton singleton::instance; // 类外初始化