---恢复内容开始---
单例模式实现方式:将构造函数、拷贝构造函数、赋值构造函数声明为私有的。然后因为不能够创建对象,所以我们必须提供一个接口用于创建一个对象。必须将其声明为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 }
---恢复内容结束---