单例应该是我接触的第一个设计模式,当时是需要一个读取和保存配置文件的方法类,由于多处需要用到,经过了解知道了单例模式,进而知道了设计模式
概述
单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象创建型模式。
结构
定义一个单例类:
- 私有化它的构造函数,以防止外界创建单例类的对象;
- 使用类的私有静态指针变量指向类的唯一实例;
- 使用一个公有的静态方法获取该实例。
最直观的实现方式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Singleton { private: Singleton(){cout<< "creat Singleton" <<endl;} static Singleton *instance; public: static Singleton *getInstance() { if (instance != NULL) { instance = new Singleton(); } return instance; } }; Singleton* Singleton::instance = NULL;
|
上面这种实现是线程不安全的,容易出现重入的问题,所以需要进行优化
代码实现
单例有两种最常见模式:懒汉模式和饿汉模式
上面的实现就是典型的懒汉模式,考虑上线程安全,我们加上锁:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Singleton { private: Singleton(){cout<< "creat Singleton" <<endl;} static Singleton *instance; static pthread_mutex_t mutex; public: static Singleton *getInstance() { if (instance == nullptr) { pthread_mutex_lock(&mutex); if (instance == nullptr) { instance = new Singleton(); } pthread_mutex_unlock(&mutex); } return instance; } }; pthread_mutex_t Singleton::mutex; Singleton* Singleton::instance = nullptr;
|
饿汉模式就是在未进入main函数时就先创建好单例,如果没有使用会造成内存的浪费,我之前喜欢使用这种方式,因为简单:
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Singleton { private: Singleton(){cout<< "creat Singleton" <<endl;} static Singleton *instance; public: static Singleton *getInstance() { return instance; } }; Singleton* Singleton::instance = new Singleton();
|
最近看到知乎上有个更优雅的方式实现单例,不过需要在C++0x之后的版本使用:
1 2 3 4 5 6 7 8 9 10 11
| class Singleton { private: Singleton(){cout<< "creat Singleton" <<endl;} public: static Singleton& getInstance() { static Singleton instance; return instance; } };
|