設計模式——單例模式
阿新 • • 發佈:2020-08-16
單例模式
通常我們可以讓一個全域性變數使得一個物件被訪問, 但它不能防止你例項化多個物件。
一個最好的辦法是, 讓類自身負責儲存它的唯一例項。 這個類可以保證沒有其他例項可以被建立, 並且提供一個可以訪問該例項的方法。
1. 有缺陷的方式
#include <iostream> using std::cout; using std::endl; class Singleton // 單例模式 { private: static Singleton* m_instance_ptr; Singleton() // 將構造放在私有位置, 防止其他例項被建立 { }public: static Singleton *GetInstance() { if (m_instance_ptr == nullptr) { m_instance_ptr = new Singleton; } return m_instance_ptr; } ~Singleton() { } }; Singleton* Singleton::m_instance_ptr = nullptr; int main() { Singleton*s1 = Singleton::GetInstance(); Singleton *s2 = Singleton::GetInstance(); cout << s1 << endl; cout << s2 << endl; system("pause"); return 0; }
問題:
執行緒安全問題:加鎖
記憶體洩漏問題:沒有辦法呼叫解構函式, 使用智慧指標
#include <iostream> #include <memory> #include <windows.h> #include<process.h> using std::cout; using std::endl; class Singleton // 單例模式 { public: typedef std::shared_ptr<Singleton> Ptr; private: static Ptr m_instance_ptr; static HANDLE m_hMutex; Singleton() // 將構造放在私有位置, 防止其他例項被建立 { } public: static Ptr GetInstance() { if (m_instance_ptr == nullptr) { WaitForSingleObject(m_hMutex, NULL); // 請求鎖 if (m_instance_ptr == nullptr) { m_instance_ptr = Ptr(new Singleton); } ReleaseMutex(m_hMutex); } return m_instance_ptr; } ~Singleton() { cout << "析構" << endl; CloseHandle(m_hMutex); } }; Singleton::Ptr Singleton::m_instance_ptr = nullptr; HANDLE Singleton::m_hMutex = CreateMutex(NULL, TRUE, NULL); unsigned __stdcall Thread_1( void * arg) { Singleton::Ptr s = Singleton::GetInstance(); cout << "thread_1 end" << endl; return 0; } unsigned __stdcall Thread_2( void * arg) { Singleton::Ptr s = Singleton::GetInstance(); cout << "thread_2 end" << endl; return 0; } int main() { { HANDLE hThread_1 = (HANDLE)_beginthreadex(NULL, 0, Thread_1, NULL, 0, NULL); HANDLE hThread_2 = (HANDLE)_beginthreadex(NULL, 0, Thread_1, NULL, 0, NULL); } system("pause"); return 0; }