1. 程式人生 > 實用技巧 >設計模式——單例模式

設計模式——單例模式

單例模式

通常我們可以讓一個全域性變數使得一個物件被訪問, 但它不能防止你例項化多個物件。

一個最好的辦法是, 讓類自身負責儲存它的唯一例項。 這個類可以保證沒有其他例項可以被建立, 並且提供一個可以訪問該例項的方法。

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; }