因为在设计或开发中,肯定会有这么一种情况,一个类只能有一个对象被创建,如果有多个对象的话,可能会导 致状态的混乱和不一致。这种情况下,单例模式是最恰当的解决办法。它有很多种实现方式,各自的特性不相同,使 用的情形也不相同。今天要实现的是常用的三种,分别是饿汉式、懒汉式和多线程式。
单例模式的要点有三个:
- 单例类只能有一个实例
- 它必须自行创建这个实例
- 它必须自行向整个系统提供提供这个实例。
从具体实现角度来说,就是以下三点: - 单例模式的类只提供私有的构造函数
- 类定义中含有一个该类的静态私有对象
- 该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象
单例模式的一些注意点:
1.实例控制:单例模式会阻止其他对象实例化自己的单例对象的副本,从而确保所有对象都访问唯一 实例
2.灵活性:因为类控制实例化过程,所以类可以灵活更改实例化过程
3.开销:虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销, 这个问题可以通过静态初始化解决此问题定义一个私有的静态指针,和一个公有的静态函数
单例模式的优点:
1. 在内存中只有一个对象,节省内存空间
2. 避免频繁的创建销毁对象,可以提高性能
3. 避免对共享资源的多重占用
4. 可以全局访问
单例模式的适用场景:
1. 需要频繁实例化然后销毁的对象
2. 创建对象耗时过多或者耗资源过多,但又经常用到的对象
3. 有状态的工具类对象
4. 频繁访问数据库或文件的对象
5. 以及其他要求只有一个对象的场景
接下来写一个懒汉式单例,代码如下:
头文件代码:
class BookManager
{
public:
static BookManager * bookmanager(); //静态方法 ,供外界获取它的静态实例。(公有静态函数)
private:
static BookManager *p; //私有静态指针
double Capital; //拥有资金
double Earnings; //收益
BookManager() { Capital = 1000; Earnings = 0; } //让构造函数为 private,这样该类就不会被实例化
}
懒汉式的特点:
Lazy 初始化
非多线程安全
优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁(在“线程安全”部分分享如何加锁)才能保证单例,但加锁会影响效率。
源文件代码:
BookManager *BookManager::p = NULL; //私有静态指针(静态成员变量必须在类外面初始化)
BookManager * BookManager::bookmanager() //静态方法,供外界获取它的静态实例。(公有静态函数)
{
if (p == NULL)
{
p = new BookManager;
}
return p;
}