单例模式

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

  单例模式实现方式:将构造函数、拷贝构造函数、赋值构造函数声明为私有的。然后因为不能够创建对象,所以我们必须提供一个接口用于创建一个对象。必须将其声明为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());//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<memory>
 3  using namespace std;
 4  class Singleton
 5  {
 6  public:
 7      static Singleton&  Getinstance()
 8      {
 9            static  Singleton instance;//局部静态对象是在运行期初始化。下一次再进入还是先前的对象。
10            return instance;//返回了引用
11     }
12      ~Singleton() { cout << "~Singleton" << endl; }//会调用析构函数
13  private:
14      Singleton() { pthread_mutex_init(&mutex) };
15      Singleton(const Singleton& other) {};
16      Singleton& operator=(const Singleton& other) {};
17  };
18  int main()
19  {
20      Singleton&  s1 = Singleton::Getinstance();
21     Singleton&  s2 = Singleton::Getinstance();
22      return 0;
23  }

 

 

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

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

 

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

posted on 2017-10-16 18:36  wsw_seu  阅读(227)  评论(0编辑  收藏  举报

导航