23种设计模式C++源码与UML实现--单例模式中的饿汉模式和懒汉模式
單例模式
單例模式是一種對象創建模式,使用單例模式,可以保證為一個類生成唯一的實例對象。也就是說在這個程序空間該類只有一個實例對象。
GoF對單例的定義:保證一個類、只有一個實例存在,同時提供對該實例加以訪問的全局訪問方法。
單例模式UML圖
單例模式的目的就是保證一個類只有一個實例,并提供一個訪問它的全局訪問點。
使用單例模式的原因
在應用系統開發中,我們常常有以下需求:
- 多個線程公用一個socket資源,或者操作同一個對象
- 在整個程序空間需要使用全局變量,共享資源
- 大規模系統中,為了性能考慮,需要節省對象創建的時間等
實現步驟:
構造函數私有化的作用:構造函數私有化之后,則構造該類的對象,必須在類內部完成。
懶漢式單例模式
叫懶漢式的原因,是因為只有再用的時候才會創建類中的全局指針。
代碼實現如下:
#include <iostream>using namespace std;class Singleton { private:Singleton(){cout << "sluggard singleton construct start." << endl;}public:static Singleton *getInstance(void){if(NULL == m_psl) // 懶漢式,每次獲取實例都要判斷,在多線程中會存在問題{m_psl = new Singleton;}return m_psl;}static void FreeInstance(){if(NULL != m_psl){delete m_psl;m_psl = NULL;}} private:static Singleton *m_psl; };// 靜態變量初始化的方法,要放到類的外面 Singleton *Singleton::m_psl = NULL;// 懶漢式,只有在使用的時候才會去創建 // 存在的問題,多個線程同時首次調用時,可能會出現創建多次的問題(導致內存泄漏)int main(int argc, char const *argv[]) {// 使用功能去全局獲取接口獲取資源Singleton *p1 = Singleton::getInstance(); Singleton *p2 = Singleton::getInstance();if(p1 == p2){cout << "p1 equal p2" << endl;}else{cout << "p1 not equal p2" << endl;}// 手動釋放單例模式創建的唯一一個對象Singleton::FreeInstance();cout << "singleton." << endl;return 0; }編譯之后輸出結果:
sluggard singleton construct start. p1 equal p2 singleton.餓漢式
餓漢式,與懶漢式唯一的差別就是創建方式上,懶漢式是在首次調用的時候才創建,餓漢式是不管是否調用,在靜態指針初始化的時候就創建指針指向的對象。
#include <iostream>using namespace std;class Singleton { private:Singleton(){cout << "sluggard singleton construct start." << endl;}public:static Singleton *getInstance(void){return m_psl;}static void FreeInstance(){if(NULL != m_psl){delete m_psl;m_psl = NULL;}} private:static Singleton *m_psl; };// 靜態變量初始化的方法,要放到類的外面 // 餓漢式是在初始化指變量的時候就對其進行創建,不管是否被調用 Singleton *Singleton::m_psl = new Singleton;int main(int argc, char const *argv[]) {// 使用功能去全局獲取接口獲取資源Singleton *p1 = Singleton::getInstance(); Singleton *p2 = Singleton::getInstance();if(p1 == p2){cout << "p1 equal p2" << endl;}else{cout << "p1 not equal p2" << endl;}// 手動釋放單例模式創建的唯一一個對象Singleton::FreeInstance();cout << "singleton." << endl;return 0; }餓漢式執行之后輸出結果:
sluggard singleton construct start. p1 equal p2 hungry singleton.兩者分析:
懶漢式因為使用的時候才會創建內存,所以當多個線程同時使用的時候可能會出現多次創建的問題,餓漢式不存在這個問題。
懶漢式雖然有有點,但是每次調用GetInstance()靜態方法都必須判斷靜態指針是否為NULL使程序相對開銷增大,多喜愛能成中會導致多個實例產生,從而導致運行代碼不正確以及內存泄漏,也有可能是多次釋放資源。
這是因為C++中構造函數并不是線程安全的,C++中的構造函數簡單分為兩步
由于多線程的關系,可能內存放分配好,還沒有給成員賦值,就發生了線程切換,導致下個線程中又申請了一遍內存。
總結
以上是生活随笔為你收集整理的23种设计模式C++源码与UML实现--单例模式中的饿汉模式和懒汉模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring 多数据源 总结
- 下一篇: c++中的 单例模式(singleton