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++如何使用智能指针实现模板形式的单例类”有了一定的了解,如果想了解更多相关知识,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

推荐阅读:
  1. 单例类模板(五十一)
  2. 智能指针类模板(五十)

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++

上一篇:Java异步之call future的示例分析

下一篇:安装Docker Desktop报错WSL 2 installation is incomplete怎么办

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》