第一種:單線程(懶漢)
第二種:多線程(互斥量實現鎖+懶漢)
第三種:多線程(const static+餓漢)(還要繼續了解)
//單線程解法 //這種解法在多線程的情況下,可能創建多個實例。
class Singleton1 { private: static Singleton1* m_pInstance1;//需要的時候才創建,懶漢 //利用static關鍵字的特性,不屬於任何類,整個類只有一個
Singleton1(); public: static Singleton1* GetInstance1(); static void DestroyInstance1(); }; Singleton1::Singleton1() { cout << "創建單例" << endl; } Singleton1* Singleton1::GetInstance1() { return m_pInstance1; } void Singleton1::DestroyInstance1() { if (m_pInstance1 != nullptr) { delete m_pInstance1; m_pInstance1 = nullptr; } } //初始化一個對象
Singleton1* Singleton1::m_pInstance1 = new Singleton1(); //單線程下多次獲取實例
void test1() { Singleton1* singletoObj1 = Singleton1::GetInstance1(); cout << singletoObj1 << endl; Singleton1* singletoObj2 = Singleton1::GetInstance1(); cout << singletoObj2 << endl; //上面的兩個對象會指向同一個地址
Singleton1::DestroyInstance1(); }
//多線程+加鎖(互斥量)
class Singleton2 { private: Singleton2(); static Singleton2* m_pInstance2; static mutex m_mutex;//互斥量
public: static Singleton2* GetInstance2(); static void DestroyInstance2(); }; Singleton2::Singleton2() { cout << "創建單例2" << endl; } Singleton2* Singleton2::GetInstance2() { if (m_pInstance2 == nullptr) { cout << "加鎖中" << endl; m_mutex.lock(); if (m_pInstance2 == nullptr) { m_pInstance2 = new Singleton2(); } cout << "解鎖中" << endl; m_mutex.unlock(); } return m_pInstance2; } void Singleton2::DestroyInstance2() { if (m_pInstance2 != nullptr) { delete m_pInstance2; m_pInstance2 = nullptr; } } //靜態成員變量的定義
Singleton2* Singleton2::m_pInstance2 = nullptr;//懶漢式的寫法
mutex Singleton2::m_mutex; //常見一個實例對象,給下面的多線程調用
void print_singleton_instance() { Singleton2* singletonObj2 = Singleton2::GetInstance2(); cout << "新的一個實例對象" << singletonObj2 << endl; } void test2() { vector<thread> threads; for (int i = 0; i < 10; i++) { //十個線程都指向同一個靜態變量的地址
threads.push_back(thread(print_singleton_instance)); } for (auto& thr : threads) { thr.join(); } }
//方案三:使用const特性,來替換方案二的加鎖操作
class Singleton3 { private: Singleton3(){} static const Singleton3* m_pInstance3; public: static Singleton3* GetInstance3(); static void DestroyInstance3(); }; Singleton3* Singleton3::GetInstance3() { //這個函數的返回值如果變化曾const static屬性,就不用進行const_cast
return const_cast<Singleton3*> (m_pInstance3); } void Singleton3::DestroyInstance3() { if (m_pInstance3 != nullptr) { delete m_pInstance3; m_pInstance3 = nullptr; } } //靜態成員變量的定義
const Singleton3* Singleton3::m_pInstance3 = new Singleton3();//餓漢式的寫法 //常見一個實例對象,給下面的多線程調用
void print_singleton_instance3() { Singleton3* singletonObj3 = Singleton3::GetInstance3(); cout << "新的一個實例對象" << singletonObj3 << endl; } void test3() { vector<thread> threads; for (int i = 0; i < 10; i++) { //十個線程都指向同一個靜態變量的地址
threads.push_back(thread(print_singleton_instance3)); } for (auto& thr : threads) { thr.join(); } }