c++单例模式

单例模式的意图:一个类只能有一个实例。

//单例模式:

懒汉模式:在需要时才创建。需要考虑线程安全。

饿汉模式:系统一运行就构造初始化,不需要考虑线程安全。

 //以下是懒汉模式:

//非线程安全版本

 1 class Singleton{
 2 private:
 3     Singleton();
 4     Singleton(const Singleton &);
 5 public:
 6     static Singleton* init;
 7     static Singleton* getSingleton();
 8 };
 9 Singleton* Singleton::init = nullptr;
10 Singleton * Singleton::getSingleton() {
11     if(init == nullptr){
12         init = new Singleton();
13     }
14     return init;
15 }

 

//线程安全版本,但是加锁的代价过高

//多个线程读的时候其实不需要锁,面对高并发的情况,这个锁的代价比较高

 1 class Singleton {
 2 private:
 3     Singleton();
 4 
 5     Singleton(const Singleton &);
 6 
 7     ~Singleton();
 8 
 9     const Singleton &operator=(const Singleton &other);
10 
11 public:
12     static mutex m_mutex;
13     static Singleton *m_instance;
14 
15     static Singleton *getSingleton();
16 };
17 
18 mutex Singleton::m_mutex;
19 Singleton *Singleton::m_instance = nullptr;
20 
21 Singleton *Singleton::getSingleton() {
22     unique_lock<mutex> lock1(m_mutex);
23     if (m_instance == nullptr) {
24         m_instance = new Singleton();
25     }
26     return m_instance;
27 }

 

 

//双检查锁,但是由于内存读写reorder不安全。

//锁后检查避免多次实例,锁前检查防止两个线程都进了16行之后17行之前,lock等待了之后又实例化。

第19行,执行的顺序是:1.先分配内存,2.调用构造器 3.把这片内存地址值返回给init;

但是由于线程在指令层次抢时间片;那么实际的执行指令顺序未必和上述相同。 

 

 1 class Singleton{
 2 private:
 3     Singleton();
 4     Singleton(const Singleton &);
 5     ~Singleton();
 6     const Singleton & operator=(const Singleton & other);
 7 public:
 8     static mutex m_mutex;
 9     static Singleton* m_instance;
10     static Singleton* getSingleton();
11 };
12 
13 mutex Singleton::m_mutex;
14 Singleton* Singleton::m_instance = nullptr;
15 Singleton * Singleton::getSingleton() {
16     if(m_instance== nullptr){
17         unique_lock<mutex> lock1(m_mutex);
18         if(m_instance == nullptr){
19             m_instance = new Singleton();
20         }
21     }
22     return m_instance;
23 }

 

 

//c++11版本之后的跨平台实现

 

 1 class Singleton {
 2 private:
 3     Singleton();
 4 
 5     Singleton(const Singleton &);
 6 
 7     ~Singleton();
 8 
 9     const Singleton &operator=(const Singleton &other);
10 
11 public:
12     static mutex m_mutex;
13     static Singleton *m_instance;
14 
15     static Singleton *getSingleton();
16 };
17 
18 mutex Singleton::m_mutex;
19 Singleton *Singleton::m_instance = nullptr;
20 
21 Singleton *Singleton::getSingleton() {
22     if (m_instance == nullptr) {
23         unique_lock<mutex> lock1(m_mutex);
24         if (m_instance == nullptr) {
25            Singleton * temp = static_cast<Singleton*>(operator new(sizeof(Singleton)));
26            new(temp)Singleton();//temp指针上调用Singleton的构造函数
27            m_instance = temp;
28         }
29     }
30     return m_instance;
31 }

 

 

//饿汉模式

系统一运行就有一个实例化的对象。

 1 class Singleton {
 2 private:
 3     Singleton();
 4     Singleton(const Singleton &);
 5     ~Singleton();
 6     const Singleton &operator=(const Singleton &other);
 7     static Singleton *m_instance;
 8 public:
 9     static Singleton*getS();
10 };
11 Singleton *Singleton::m_instance = new Singleton();
12 Singleton *Singleton::getS() {
13     return m_instance;
14 }

 

posted @ 2022-08-24 10:16  coyote25  阅读(68)  评论(0编辑  收藏  举报