23种设计模式C++源码与UML实现--单例模式中的饿汉模式和懒汉模式
單例模式
單例模式是一種對象創(chuàng)建模式,使用單例模式,可以保證為一個類生成唯一的實例對象。也就是說在這個程序空間該類只有一個實例對象。
GoF對單例的定義:保證一個類、只有一個實例存在,同時提供對該實例加以訪問的全局訪問方法。
單例模式UML圖
單例模式的目的就是保證一個類只有一個實例,并提供一個訪問它的全局訪問點。
使用單例模式的原因
在應(yīng)用系統(tǒng)開發(fā)中,我們常常有以下需求:
- 多個線程公用一個socket資源,或者操作同一個對象
- 在整個程序空間需要使用全局變量,共享資源
- 大規(guī)模系統(tǒng)中,為了性能考慮,需要節(jié)省對象創(chuàng)建的時間等
實現(xiàn)步驟:
構(gòu)造函數(shù)私有化的作用:構(gòu)造函數(shù)私有化之后,則構(gòu)造該類的對象,必須在類內(nèi)部完成。
懶漢式單例模式
叫懶漢式的原因,是因為只有再用的時候才會創(chuàng)建類中的全局指針。
代碼實現(xiàn)如下:
#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; };// 靜態(tài)變量初始化的方法,要放到類的外面 Singleton *Singleton::m_psl = NULL;// 懶漢式,只有在使用的時候才會去創(chuàng)建 // 存在的問題,多個線程同時首次調(diào)用時,可能會出現(xiàn)創(chuàng)建多次的問題(導致內(nèi)存泄漏)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;}// 手動釋放單例模式創(chuàng)建的唯一一個對象Singleton::FreeInstance();cout << "singleton." << endl;return 0; }編譯之后輸出結(jié)果:
sluggard singleton construct start. p1 equal p2 singleton.餓漢式
餓漢式,與懶漢式唯一的差別就是創(chuàng)建方式上,懶漢式是在首次調(diào)用的時候才創(chuàng)建,餓漢式是不管是否調(diào)用,在靜態(tài)指針初始化的時候就創(chuàng)建指針指向的對象。
#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; };// 靜態(tài)變量初始化的方法,要放到類的外面 // 餓漢式是在初始化指變量的時候就對其進行創(chuàng)建,不管是否被調(diào)用 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;}// 手動釋放單例模式創(chuàng)建的唯一一個對象Singleton::FreeInstance();cout << "singleton." << endl;return 0; }餓漢式執(zhí)行之后輸出結(jié)果:
sluggard singleton construct start. p1 equal p2 hungry singleton.兩者分析:
懶漢式因為使用的時候才會創(chuàng)建內(nèi)存,所以當多個線程同時使用的時候可能會出現(xiàn)多次創(chuàng)建的問題,餓漢式不存在這個問題。
懶漢式雖然有有點,但是每次調(diào)用GetInstance()靜態(tài)方法都必須判斷靜態(tài)指針是否為NULL使程序相對開銷增大,多喜愛能成中會導致多個實例產(chǎn)生,從而導致運行代碼不正確以及內(nèi)存泄漏,也有可能是多次釋放資源。
這是因為C++中構(gòu)造函數(shù)并不是線程安全的,C++中的構(gòu)造函數(shù)簡單分為兩步
由于多線程的關(guān)系,可能內(nèi)存放分配好,還沒有給成員賦值,就發(fā)生了線程切換,導致下個線程中又申請了一遍內(nèi)存。
總結(jié)
以上是生活随笔為你收集整理的23种设计模式C++源码与UML实现--单例模式中的饿汉模式和懒汉模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring 多数据源 总结
- 下一篇: 【2015年第4期】大数据时代的数据挖掘