单例模式

Posted wsw_seu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式相关的知识,希望对你有一定的参考价值。

---恢复内容开始---

  单例模式实现方式:将构造函数、拷贝构造函数、赋值构造函数声明为私有的。然后因为不能够创建对象,所以我们必须提供一个接口用于创建一个对象。必须将其声明为static静态成员函数,是指属于类而不属于对象,即整个类只有一份。静态成员函数只能访问静态数据成员,所以数据成员也要声明为静态的。

  

 1 #include<iostream>
 2 using namespace std;
 3 class Singleton
 4 {
 5 public:
 6     static Singleton* Getinstance()
 7     {
 8         //只能构造一个
 9         if (p == NULL)
10             p = new Singleton();
11         return p;
12     }
13     ~Singleton() { cout << "~Singleton" << endl; }//并未调用析构函数
14 private:
15     Singleton() { cout << "Singleton" << endl; };
16     Singleton(const Singleton& other) {};
17     Singleton& operator=(const Singleton& other) {};
18     static Singleton* p;
19 };
20 Singleton* Singleton::p = NULL;
21 int main()
22 {
23     Singleton* s1 = Singleton::Getinstance();
24     Singleton* s2 = Singleton::Getinstance();
25     return 0;
26 }

  上述单例模式的实现存在两个问题,一是它并未调用析构函数,存在内存泄漏;而是它并不是线程安全的。首先解决内存泄漏问题。引入auto_ptr智能指针即可解决。

 1 #include<iostream>
 2 #include<memory>
 3 using namespace std;
 4 class Singleton
 5 {
 6 public:
 7     static Singleton* Getinstance()
 8     {
 9         //p.get()返回原生指针。
10         if (!p.get())
11             p = auto_ptr<Singleton>(new Singleton);
12         return p.get();
13     }
14     ~Singleton() { cout << "~Singleton" << endl; }//并未调用析构函数
15 private:
16     Singleton() { cout << "Singleton" << endl; };
17     Singleton(const Singleton& other) {};
18     Singleton& operator=(const Singleton& other) {};
19     //static Singleton* p;
20     //将裸指针用智能指针来管理
21     static auto_ptr<Singleton> p;//析构函数会被调用
22 };
23 auto_ptr<Singleton> Singleton::p;
24 int main()
25 {
26     Singleton* s1 = Singleton::Getinstance();
27     Singleton* s2 = Singleton::Getinstance();
28     return 0;
29 }

  第二个问题,要解决线程安全问题,可以引入互斥量。在创建单例对象的时候进行加锁。

 1 #include<iostream>
 2 #include<pthread.h>
 3 using namespace std;
 4 class Singleton
 5 {
 6 public:
 7     static Singleton* Getinstance()
 8     {
 9         pthread_mutex_lock(&mutex);
10         if (p == NULL)
11             p = new Singleton();
12         pthread_mutex_unlock(&mutex);
13         return p;
14     }
15     ~Singleton() { cout << "~Singleton" << endl; }//并未调用析构函数
16 private:
17     Singleton() { pthread_mutex_init(&mutex) };
18     Singleton(const Singleton& other) {};
19     Singleton& operator=(const Singleton& other) {};
20     static Singleton* p;
21     static pthread_mutex_t mutex;
22 };
23 Singleton* Singleton::p;
24 pthread_mutex_t Singleton::mutex;
25 int main()
26 {
27     Singleton* s1 = Singleton::Getinstance();
28     Singleton* s2 = Singleton::Getinstance();
29     return 0;
30 }

 

---恢复内容结束---

以上是关于单例模式的主要内容,如果未能解决你的问题,请参考以下文章

常用代码片段

性能比较好的单例写法

片段作为 Android 中的单例

单例片段或保存网页视图状态

你熟悉的设计模式都有哪些?写出单例模式的实现代码

单例模式以及静态代码块