您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關C++如何實現單例模式的自動釋放,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
單例模式是為了確保某個類只能創建一個對象而設計的。當一個程序的某個類型只允許有一個實例的時候使用。
一般采用動態分配的方式來生成單例對象,這個時候C++程序員就需要考慮內存回收的問題了,所以為了避免在使用單例模式時忘記回收資源而造成內存泄漏的問題,在實現單例模式的時候就使其可以自動被回收。
我們先來復習一下沒有自動回收機制的單例模式的實現和銷毀。
單例模式的實現:
將構造函數私有化
在類中定義一個靜態的指向本類型的指針變量
定義一個返回值為該類的指針的靜態成員函數,在類的外部調用該函數,生成單例對象。
單例模式的銷毀:
不能在析構函數中釋放那個指向本類型的指針變量
需要用靜態的成員函數回收指向本類型的指針變量,然后在類的外部調用該成員函數來銷毀該單例對象。
主要思想是,利用C++棧對象消亡是會自動回收的特點,來自動回收分配在堆上的單例對象,可以通過四種方法:友元類、內部類+靜態數據成員、atexit()函數、pthread_once()+atexit()來實現
廢話不多說,直接上代碼。
1.借助友元類
//利用友元類,實現單例模式的自動釋放 #include <stdio.h> #include <iostream> using std::cout; using std::endl; using std::cin; class AutoRelease; class Singleton{ //單例模式的類 public: static Singleton *getInstance();//返回單例指針 private: friend class AutoRelease; Singleton(); //構造函數和析構函數都得是private ~Singleton(); static Singleton *_pInstance; }; Singleton *Singleton::getInstance(){ if(_pInstance == nullptr){ _pInstance = new Singleton(); } return _pInstance; } Singleton::Singleton() { cout << "Singleton()" << endl; } Singleton::~Singleton(){ cout << "~Singleton()" << endl; } class AutoRelease{ //用來實現單例的自動釋放的類 //應該保存在棧上,程序結束時自動回收單例的資源 public: AutoRelease(){ cout << "AutoRelease()" << endl; } ~AutoRelease(){ cout << "~AutoRelease()" << endl; if(Singleton::_pInstance == nullptr){ return; } delete Singleton::_pInstance; Singleton::_pInstance = nullptr; } }; Singleton *Singleton::_pInstance = nullptr; //飽漢模式 int main() { Singleton *s1 = Singleton::getInstance(); Singleton *s2 = Singleton::getInstance(); AutoRelease at; printf("s1 = %p\n", s1); printf("s2 = %p\n", s2); s1 = nullptr; s2 = nullptr; return 0; }
2.借助內部類和靜態數據成員
//利用內部類,實現單例模式的自動釋放 #include <stdio.h> #include <iostream> using std::cout; using std::endl; using std::cin; class Singleton{ //單例模式的類 public: static Singleton *getInstance();//返回單例指針 private: friend class AutoRelease; Singleton(); //構造函數和析構函數都得是private ~Singleton(); static Singleton *_pInstance; private: //應該設計為私有類,避免類外的其他成員使用 class AutoRelease{ //用來實現單例的自動釋放的內部類 //應該保存在棧上,程序結束時自動回收單例的資源 public: AutoRelease(){ cout << "AutoRelease()" << endl; } ~AutoRelease(){ cout << "~AutoRelease()" << endl; if(Singleton::_pInstance == nullptr){ return; } delete Singleton::_pInstance; Singleton::_pInstance = nullptr; } }; private: static AutoRelease _at; //由于AutoRelease是private,所以對象應該放在靜態區 }; Singleton *Singleton::getInstance(){ if(_pInstance == nullptr){ _pInstance = new Singleton(); } return _pInstance; } Singleton::Singleton() { cout << "Singleton()" << endl; } Singleton::~Singleton(){ cout << "~Singleton()" << endl; } /* Singleton *Singleton::_pInstance = nullptr; //飽漢模式 */ //飽漢模式多線程時不安全,需要使用餓漢模式,在程序跑起來前就生成單例對象 Singleton *Singleton::_pInstance = Singleton::getInstance();//餓漢模式 Singleton::AutoRelease Singleton::_at; int main() { Singleton *s1 = Singleton::getInstance(); Singleton *s2 = Singleton::getInstance(); printf("s1 = %p\n", s1); printf("s2 = %p\n", s2); s1 = nullptr; s2 = nullptr; return 0; }
3.借助atexit()函數
//利用atexit函數,實現單例模式的自動釋放 #include <stdio.h> #include <iostream> using std::cout; using std::endl; using std::cin; class Singleton{ //單例模式的類 public: static Singleton *getInstance();//返回單例指針 static void destroy(); private: friend class AutoRelease; Singleton(); //構造函數和析構函數都得是private ~Singleton(); static Singleton *_pInstance; }; Singleton *Singleton::getInstance(){ if(_pInstance == nullptr){ _pInstance = new Singleton(); //注冊destroy函數,在進程結束的時候執行,從而自動回收單例 atexit(Singleton::destroy); } return _pInstance; } void Singleton::destroy(){ if(Singleton::_pInstance == nullptr){ return; } delete Singleton::_pInstance; Singleton::_pInstance = nullptr; } Singleton::Singleton() { cout << "Singleton()" << endl; } Singleton::~Singleton(){ cout << "~Singleton()" << endl; } //為了保證多線程情況下的安全性,使用餓漢模式 Singleton *Singleton::_pInstance = Singleton::getInstance(); //餓漢模式 int main() { Singleton *s1 = Singleton::getInstance(); Singleton *s2 = Singleton::getInstance(); printf("s1 = %p\n", s1); printf("s2 = %p\n", s2); s1 = nullptr; s2 = nullptr; return 0; }
4.借助pthread_once和atexit函數
//利用pthread_once和atexit函數,實現單例模式的自動釋放 #include <stdio.h> #include <iostream> using std::cout; using std::endl; using std::cin; class Singleton{ //單例模式的類 public: static void init(); static Singleton *getInstance();//返回單例指針 static void destroy(); private: friend class AutoRelease; Singleton(); //構造函數和析構函數都得是private ~Singleton(); static pthread_once_t _once; static Singleton *_pInstance; }; void Singleton::init(){ //初始化單例,注冊回收函數 if(_pInstance == nullptr){ _pInstance = new Singleton(); atexit(Singleton::destroy); } } Singleton *Singleton::getInstance(){ //執行pthread_once,保證在多線程的情況下創建單例對象的安全性 pthread_once(&_once, init); return _pInstance; } void Singleton::destroy(){ if(Singleton::_pInstance == nullptr){ return; } delete Singleton::_pInstance; Singleton::_pInstance = nullptr; } Singleton::Singleton() { cout << "Singleton()" << endl; } Singleton::~Singleton(){ cout << "~Singleton()" << endl; } //由于已經使用了pthread_once來保證安全性,所以使用飽漢模式即可 Singleton *Singleton::_pInstance = nullptr; /* Singleton *Singleton::_pInstance = Singleton::getInstance(); //餓漢模式 */ pthread_once_t Singleton::_once = PTHREAD_ONCE_INIT; int main() { Singleton *s1 = Singleton::getInstance(); Singleton *s2 = Singleton::getInstance(); printf("s1 = %p\n", s1); printf("s2 = %p\n", s2); s1 = nullptr; s2 = nullptr; return 0; }
關于“C++如何實現單例模式的自動釋放”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。