亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++如何使用智能指針實現模板形式的單例類

發布時間:2021-06-15 09:19:03 來源:億速云 閱讀:268 作者:小新 欄目:開發技術

小編給大家分享一下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++如何使用智能指針實現模板形式的單例類”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

c++
AI

安吉县| 尚义县| 来安县| 泸定县| 湟源县| 蕉岭县| 杨浦区| 家居| 汝南县| 东光县| 虞城县| 西城区| 宝山区| 新兴县| 青龙| 定州市| 怀仁县| 扶沟县| 青岛市| 织金县| 永宁县| 阿克苏市| 拜泉县| 安龙县| 沈丘县| 资兴市| 安远县| 徐水县| 德令哈市| 丘北县| 宣威市| 泰宁县| 邮箱| 华坪县| 巴林左旗| 鄯善县| 东丰县| 米易县| 兴城市| 汤阴县| 旬邑县|