您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“C++單例模式的懶漢模式和餓漢模式怎么實現”,內容詳細,步驟清晰,細節處理妥當,希望這篇“C++單例模式的懶漢模式和餓漢模式怎么實現”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
懶漢模式在第一次用到類實例的時候才會去實例化,就是不到調用getInstance函數時,這個類的對象是一直不存在的。懶漢本身是線程不安全的。
#include <iostream> using namespace std; class Singelton{ private: Singelton(){ m_count ++; printf("Singelton begin\n"); Sleep(1000);// 加sleep為了放大效果 printf("Singelton end\n"); } static Singelton *single;//定義一個唯一指向實例的指針,并且是私有的 public: static Singelton *GetSingelton();//定義一個公有函數,可以獲取這個唯一實例 static void print(); static int m_count; }; //將唯一指向實例的指針初始化為nullptr Singelton *Singelton::single = nullptr; int Singelton::m_count = 0; Singelton *Singelton::GetSingelton(){ if(single == nullptr){//判斷是不是第一次使用 single = new Singelton; } return single; } void Singelton::print(){ cout<<m_count<<endl; } int main() { singleton* a1 = singleton::GetInstance(); cout << a1 << endl; a1->print(); singleton* a2 = singleton::GetInstance(); cout << a2 << endl; a2->print(); system("pause"); return 0; }
懶漢模式的singleton類有以下特點:
1.他有一個指向唯一實例的靜態指針,并且是私有的。
2.它有一個公有的函數,可以獲取這個唯一的實例,并且在需要的時候創建該實例。
3.它的構造函數是私有的,這樣就不能從別處創建該類的實例。
餓漢模式在單例類定義的時候(即在main函數之前)就進行實例化。因為main函數執行之前,全局作用域的類成員靜態變量m_Instance已經初始化,故沒有多線程的問題。
#include <iostream> #include <process.h> #include <windows.h> using namespace std; class Singelton{ private: Singelton(){ m_count ++; printf("Singelton begin\n"); Sleep(1000); // 加sleep為了放大效果 printf("Singelton end\n"); } static Singelton *single;//定義一個唯一指向實例的指針,并且是私有的 public: static Singelton *GetSingelton();//定義一個公有函數,可以獲取這個唯一實例 static void print(); static int m_count; }; // 餓漢模式的關鍵:定義即實例化 Singelton *Singelton::single = new Singelton; int Singelton::m_count = 0; Singelton *Singelton::GetSingelton(){ // 不再需要進行實例化 //if(single == nullptr){ // single = new Singelton; //} return single; } void Singelton::print(){ cout<<m_count<<endl; } int main() { cout << "we get the instance" << endl; singleton* a1 = singleton::getinstance(); singleton* a2 = singleton::getinstance(); singleton* a3 = singleton::getinstance(); cout << "we destroy the instance" << endl; system("pause"); return 0; }
在多線程環境下,懶漢模式的上述實現方式是不安全的,原因在于在判斷instance是否為空時,可能存在多個線程同時進入if中,此時可能會實例化多個對象。于是出現了二重鎖的懶漢模式,實現代碼如下:
#include<iostream> #include<mutex> using namespace std; /*單例模式:構造函數私有化,對外提供一個接口*/ //線程安全的單例模式 class lhsingleClass { public: static lhsingleClass* getinstance() {//雙重鎖模式 if (instance == nullptr) {//先判斷是否為空,如果為空則進入,不為空說明已經存在實例,直接返回 //進入后加鎖 i_mutex.lock(); if (instance == nullptr) {//再判斷一次,確保不會因為加鎖期間多個線程同時進入 instance = new lhsingleClass(); } i_mutex.unlock();//解鎖 } return instance; } private: static lhsingleClass* instance; static mutex i_mutex;//鎖 lhsingleClass(){} }; lhsingleClass* lhsingleClass::instance=nullptr; mutex lhsingleClass::i_mutex;//類外初始化 int main() { lhsingleClass* lhsinglep5 = lhsingleClass::getinstance(); lhsingleClass* lhsinglep6 = lhsingleClass::getinstance(); cout << lhsinglep5 << endl; cout << lhsinglep6 << endl; system("pause"); return 0; }
此代碼共進行了兩次判斷:
先判斷是否為空,如果為空則進入,不為空說明已經存在實例,直接返回。
再判斷一次,確保不會因為加鎖期間多個線程同時進入。
讀到這里,這篇“C++單例模式的懶漢模式和餓漢模式怎么實現”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。