思路分析
在书写单例模式之前,我们需要先理解为什么需要单例模式
保证整个系统中一个类只有一个对象的实例,实现这种功能的方式就叫单例模式。
单例模式的优点有哪些
1、单例模式节省公共资源
比如:大家都要喝水,但是没必要每人家里都打一口井是吧,通常的做法是整个村里打一个井就够了,大家都从这个井里面打水喝。
对应到我们计算机里面,像日志管理、打印机、数据库连接池、应用配置。
2、单例模式方便控制
就像日志管理,如果多个人同时来写日志,你一笔我一笔那整个日志文件都乱七八糟,如果想要控制日志的正确性,那么必须要对关键的代码进行上锁,只能一个一个按照顺序来写,而单例模式只有一个人来向日志里写入信息方便控制,避免了这种多人干扰的问题出现。 如何实现单例模式 根据定义,显然单例模式的要点有三个:
- 某个类只能有一个实例;
- 它必须自行创建这个实例;
- 它必须自行向整个系统提供这个实例。
从具体实现角度来说:
- 单例模式的类只提供私有的构造函数;
- 类定义中含有一个该类的静态私有对象;
- 该类提供了一个静态的公有函数用于创建或者获取它本身的静态私有对象。
饿汉式
那么对于饿汉来说。他希望随时都能吃到吃的,迫切的需要吃饭,所以需要事先把饭准备好
代码实现
class Singleton
{
public:
static Singleton* getInstance ()
{
return &_instance;
}
private:
static Singleton _instance;
Singleton() {};
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
Singleton Singleton::_instance;
懒汉式
根据上面的原理,我们可以猜测懒汉模式就是因为这个人很懒,所以他都是等到自己很饿了之后,才会去做饭,因此我们饿汉模式就是只有当你打算使用时,我们才会进行创建实例。
- 优点:第一次使用实例对象时,创建对象。进程启动无负载。多个单例实例启动顺序自由控制
- 缺点:使用不比饿汉式流畅,实现复杂,需要自己实现线程安全
代码实现流程: 构造函数私有化,将拷贝构造和赋值运算符重载设置为删除函数,成员属性有两个,分别是静态的互斥锁和一个静态的该类指针,这个指针初始化为空。然后再类中定义静态的一个获取对象的函数。在该函数中需要双重检测,第一个检测是优化代码性能,让线程不要每次都需要加锁判断,第二个检测是用于保证对象只被创建一次,该操作需要被加锁保护。
class Singleton
{
public:
static Singleton* getInstance ()
{
if (_instance == nullptr)
{
_mutex.lock();
if (_instance == nullptr)
_instance = new Singleton();
_mutex.unlock();
}
}
private:
Singleton() {};
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton* _instance;
static mutex _mutex;
};
Singleton* Singleton::_instance = nullptr;
mutex Singleton::_mutex;
|