您好,登錄后才能下訂單哦!
小編給大家分享一下C++如何使用智能指針實現模板形式的單例類,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
本文通過實例為大家分享了java實現圖書管理系統的具體代碼,供大家參考,具體內容如下
實現一個模板形式的單例類,對于任意類型的類經過Singleton的處理之后,都能獲取一個單例對象,并且可以傳遞任意參數
并且還使用了智能指針,把生成的單例對象托管給智能指針,從而實現自動回收單例對象的資源
此外,如果需要一個放在靜態成員區的對象供其他類使用,又不希望修改原有的類的代碼,這時候可以通過該模板套一層殼,形成單例對象。
頭文件
template_singleton.hpp
#include <iostream> #include <string> #include <memory> using std::cout; using std::endl; using std::string; using std::shared_ptr; using std::make_shared; template <typename T> class Singleton; class Point { //由于構造和析構被設為私有,想使用單例模板創造對象,就應該把其設為友元 template <typename T> friend class Singleton; public: //把析構函數設為private之后,智能指針銷毀時無法調用 //所以析構應該設置為public,但是就算是共有的析構,由于是把單例對象的內容托管給了智能指針 //通過智能指針顯式的調用析構函數,也是無法回收單例對象的,所以,不影響單例模式的實現 ~Point(){ cout << "~Point()" << endl; } void show(){ cout << "(" << _ix << ", " << _iy << ")" << endl; } private: //單例模式,要把構造函數和析構函數設為私有 Point(int x, int y) : _ix(x), _iy(y) { cout << "Point(int, int)" << endl; } /* ~Point(){ */ /* cout << "~Point()" << endl; */ /* } */ private: int _ix; int _iy; }; class Computer { //由于構造和析構被設為私有,想使用單例模板創造對象,就應該把其設為友元 template <typename T> friend class Singleton; public: void show(){ cout << "name: " << _name << " price: " << _price << endl; } void reset(const string &newname, const int &newprice){ _name = newname; _price = newprice; } //使用public的析構函數,不影響單例模式的實現 ~Computer(){ cout << "~Computer()" << endl; } private: //單例模式,要把構造函數設為私有 //使用模板生成單例對象的時候調用了make_shared函數,如果傳入的是棧上的內容 //make_shared函數會調用拷貝構造函數在堆上重新生成一個托管給智能指針的對象, //并把原先的對象銷毀,所以會在make_shared里面執行一次析構函數 /* Computer(const Computer &rhs){ */ /* cout << "拷貝構造函數" << endl; */ /* } */ Computer(const string &name, const int price) :_name(name), _price(price) { cout << "Computer(const string &, const int &)" << endl; } /* ~Computer(){ */ /* cout << "~Computer()" << endl; */ /* } */ private: string _name; int _price; }; //模板形式的單例類(使用了智能指針),應該使用飽漢模式 template <typename T> class Singleton { public: template <typename ...Args> static shared_ptr<T> getInstance(Args... args){ if(_pInstance == nullptr){ //這里會直接調用相應的類型的構造函數,托管給智能指針,類型在實例化后確定 /* //使用臨時對象托管給智能指針的時候,由于臨時對象分配在棧上, */ /* //所以在make_shared內部會重新分配堆上的空間來保存其內容, */ /* //會調用拷貝構造函數,并把臨時對象銷毀 */ /* _pInstance = make_shared<T>(T(args...)); */ //如果把一個分配在堆上的指針托管給智能指針,傳入的指針就不會被銷毀 T *tmp = new T(args...); _pInstance = make_shared<T>(*tmp); } return _pInstance; } private: //由于使用了模板,所以_pInstance實際上指向的是 T ,而非本類型, //所以并不會生成Singleton對象,而是直接生成相應的T對象 //T在實例化之后才會確定,究竟是哪種類型, //所以Singleton的構造函數和析構函數并不會執行 Singleton(){ cout << "Singleton()" << endl; } ~Singleton(){ cout << "~Singleton()" << endl; } static shared_ptr<T> _pInstance; //單例模式的指針,指向唯一的實體 }; //由于類型在實例化是才會確定,所以使用飽漢模式 template <typename T> shared_ptr<T> Singleton<T>::_pInstance = nullptr;
測試文件
test_template_singleton.cc
#include "template_singleton.hpp" #include <stdio.h> using std::cout; using std::endl; using std::cin; void test(){ shared_ptr<Computer> pc1 = Singleton<Computer>::getInstance("Xiaomi", 6666); cout << "pc1: "; pc1->show(); shared_ptr<Computer> pc2 = Singleton<Computer>::getInstance("Xiaomi", 6666); cout << "pc1: "; pc1->show(); cout << "pc2: "; pc2->show(); pc2->reset("Huawei", 8888); cout << endl << "after pc2->reset()" << endl; cout << "pc1: "; pc1->show(); cout << "pc2: "; pc2->show(); cout << endl; shared_ptr<Point> pt3 = Singleton<Point>::getInstance(1, 2); shared_ptr<Point> pt4 = Singleton<Point>::getInstance(1, 2); cout << endl << "通過模板,可以生成不同類型的單例對象:" << endl; cout << "pt3: "; pt3->show(); cout << "pt4: "; pt4->show(); cout << endl << "使用了智能指針,不同對象指向的地址也一樣:" << endl; printf("&pc1 = %p\n", &pc1); printf("&pc2 = %p\n", &pc2); printf("&pt3 = %p\n", &pt3); printf("&pt4 = %p\n\n", &pt4); printf("&(*pc1) = %p\n", &(*pc1)); printf("&(*pc2) = %p\n", &(*pc2)); printf("&(*pt3) = %p\n", &(*pt3)); printf("&(*pt4) = %p\n\n", &(*pt4)); } int main() { test(); return 0; }
運行結果
Computer(const string &, const int &) pc1: name: Xiaomi price: 6666 pc1: name: Xiaomi price: 6666 pc2: name: Xiaomi price: 6666 after pc2->reset() pc1: name: Huawei price: 8888 pc2: name: Huawei price: 8888 Point(int, int) # 通過模板,可以生成不同類型的單例對象: pt3: (1, 2) pt4: (1, 2) # 使用了智能指針,不同對象指向的地址也一樣: &pc1 = 0x7ffe83bbd390 &pc2 = 0x7ffe83bbd3a0 &pt3 = 0x7ffe83bbd3b0 &pt4 = 0x7ffe83bbd3c0 &(*pc1) = 0x55b750c7e300 &(*pc2) = 0x55b750c7e300 &(*pt3) = 0x55b750c7e360 &(*pt4) = 0x55b750c7e360 ~Point() ~Computer()
看完了這篇文章,相信你對“C++如何使用智能指針實現模板形式的單例類”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。