单例模式

单例应该是我接触的第一个设计模式,当时是需要一个读取和保存配置文件的方法类,由于多处需要用到,经过了解知道了单例模式,进而知道了设计模式

概述

单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象创建型模式。

结构

定义一个单例类:

  1. 私有化它的构造函数,以防止外界创建单例类的对象;
  2. 使用类的私有静态指针变量指向类的唯一实例;
  3. 使用一个公有的静态方法获取该实例。

最直观的实现方式如下:

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;
}
};

单例模式
https://carl-5535.github.io/2022/04/24/设计模式/单例模式/
作者
Carl Chen
发布于
2022年4月24日
许可协议