设计模式-单例模式

考虑某种场景,我们需要一个工具类,对于所有模块提供同样的接口与数据,但是如果每个模块使用这个类的功能的时候都创建一整个类,此种行为虽说是合法的,但并不是最好的选择,我们可以通过单例设计模式,将这个类变为一个单例,我们每一次创建这个类的实例的时候,都只是获取之前创建的,从而调用相应的功能。

单例模式

  • 单线程版本
  • 多线程版本
  • 双检查锁
  • C++11之后的版本
  • std::call_once

实现

  • 单线程版本
    • 此版本只是单线程安全
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Singleton
{
public:
static Singleton * getInstance()
{
if(!m_singleton)
{
m_singleton = new Singleton;
}
return m_singleton;
}

sprivate:
Singleton() = default;
Singleton* m_singleton{nullptr};
};


  • 多线程版本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <mutex>
std::mutex m_mutex;
class Singleton
{
public:
static Singleton* getInstance()
{
std::unique_lock<std::mutex> lock(m_mutex);
if (!m_singleton)
{
m_singleton = new Singleton;
}
lock.unlock();
lock.release();
return m_singleton;
}

private:
Singleton() = default;
Singleton* m_singleton{ nullptr };
};

  • 多线程版本优化版 - 双检查锁
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <mutex>
std::mutex m_mutex;
class Singleton
{
public:
static Singleton* getInstance()
{
if (!m_singleton)
{
std::unique_lock<std::mutex> lock(m_mutex);
if (!m_singleton)
{
m_singleton = new Singleton;
}
lock.unlock();
lock.release();
}
return m_singleton;
}
private:
Singleton() = default;
Singleton* m_singleton{ nullptr };
};

  • C++11版本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Singleton
{
public:
static Singleton& getInstance()
{
static Singleton m_instance;
return m_instance;
}
public:
Singleton() = default;
Singleton(const Singleton& another) = delete;
Singleton(const Singleton&& another) = delete;
Singleton& operator=(const Singleton& another) = delete;
Singleton& operator=(const Singleton&& another) = delete;
};

  • std::call_once
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <thread>
#include <mutex>
#include <memory>

std::once_flag flag;

class Singleton
{
public:
static Singleton& getInstance()
{
std::call_once(flag, []() {m_instance.reset(new Singleton()); });
return *m_instance;
}

public:
Singleton() = default;
Singleton(const Singleton& another) = delete;
Singleton(const Singleton&& another) = delete;
Singleton& operator=(const Singleton& another) = delete;
Singleton& operator=(const Singleton&& another) = delete;
private:
static std::unique_ptr<Singleton> m_instance;
};
std::unique_ptr<Singleton> Singleton::m_instance;