單例物件的建立與自動釋放
阿新 • • 發佈:2022-04-06
#include <iostream> using std::cout; using std::endl; class Singleton { public: class AutoRelease { public: AutoRelease(Singleton * p) : _p(p) { } ~AutoRelease() { if(_p) { delete _p; _p = nullptr; } } Singleton* _p; }; public: static Singleton * getInstance() { if(_pInstance == nullptr) { _pInstance = new Singleton(); } return _pInstance; } static void destroy() { if(_pInstance) { delete _pInstance; _pInstance = nullptr; } }private: Singleton() { cout << "Singleton()" << endl; } ~Singleton() { cout << "~Singleton()" << endl; } int _data; static Singleton * _pInstance; }; Singleton * Singleton::_pInstance = nullptr; void test0() { Singleton * ps1 = Singleton::getInstance(); Singleton* ps2 = Singleton::getInstance(); printf("ps1:%p\n", ps1); printf("ps2:%p\n", ps2); Singleton::AutoRelease ar(ps1); //如果忘記了執行回收單例物件的操作,就會發生記憶體洩漏 //Singleton::destroy(); } int main(void) { test0(); return 0; }
#include <iostream> using std::cout; using std::endl; //單例物件的自動釋放方法一: //巢狀類 + 靜態物件 //外部類 class singleton { public: class autorelease//內部類 { //autorelease專為singleton服務 public: //在內部類內部無法直接拿到外部類的 //非靜態的資料成員的 autorelease() { //cout << _data << endl;//error cout << "autorelease()" << endl; } //在autorelease內部是可以直接拿到外部類的 //靜態資料成員_pinstance ~autorelease() { if(_pinstance) { delete _pinstance; _pinstance = nullptr; } cout << "~autorelease()" << endl; } singleton * _p; }; public: static singleton * getinstance() { if(_pinstance == nullptr) { _pinstance = new singleton(); } return _pinstance; } static void destroy() { if(_pinstance) { delete _pinstance; _pinstance = nullptr; } } private: singleton() { cout << "singleton()" << endl; } ~singleton() { cout << "~singleton()" << endl; } int _data; static autorelease _ar;//類物件成員 static singleton * _pinstance; }; singleton * singleton::_pinstance = nullptr; //靜態資料成員要在類之外初始化 singleton::autorelease singleton::_ar; void test0() { //在getinstance之中建立autorelease物件 singleton * ps1 = singleton::getinstance(); singleton * ps2 = singleton::getinstance(); printf("ps1:%p\n", ps1); printf("ps2:%p\n", ps2); //需求: 該語句不需要我們手動執行 //singleton::autorelease ar(ps1); //如果忘記了執行回收單例物件的操作,就會發生記憶體洩漏 //singleton::destroy(); } int main(void) { test0(); return 0; }
#include <stdlib.h> #include <iostream> using namespace std; class Singleton { public: static Singleton * getInstance() { if(_pInstance == nullptr) { _pInstance = new Singleton(); atexit(destroy); } return _pInstance; } private: Singleton() { cout << "Singleton()" << endl; } ~Singleton() { cout << "~Singleton()" << endl; } int _data; static Singleton * _pInstance; }; //餓漢模式 Singleton * Singleton::_pInstance = getInstance(); void test0() { Singleton * ps1 = Singleton::getInstance(); Singleton * ps2 = Singleton::getInstance(); printf("ps1:%p\n", ps1); printf("ps2:%p\n", ps2); } int main(void) { test0(); return 0; }
#include <stdlib.h> #include <pthread.h> #include <iostream> using std::cout; using std::endl; class Singleton { public: static Singleton * getInstance() { //多執行緒安全的實現,但只能在Linux平臺使用 pthread_once(&_once, init); return _pInstance; } static void init() { atexit(destroy); _pInstance = new Singleton(); } static void destroy() { if(_pInstance) { delete _pInstance; _pInstance = nullptr; } } private: Singleton() { cout << "Singleton()" << endl; } ~Singleton() { cout << "~Singleton()" << endl; } int _data; static Singleton * _pInstance; static pthread_once_t _once; }; Singleton * Singleton::_pInstance = nullptr; pthread_once_t Singleton::_once = PTHREAD_ONCE_INIT; void test0() { Singleton * ps1 = Singleton::getInstance(); Singleton * ps2 = Singleton::getInstance(); printf("ps1:%p\n", ps1); printf("ps2:%p\n", ps2); } int main(void) { test0(); return 0; }