首页 > 其他分享 >变参模板改进单例模式

变参模板改进单例模式

时间:2022-08-29 15:23:16浏览次数:56  
标签:pInstance Singleton 变参 arg0 Instance 单例 模板 构造函数

单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点 泛型单例模式需要变参构造函数,构造函数的参数个数需要支持变化 下面是不用变参模板,支持0~6个参数的单例模式实现

#include <iostream>

// 泛型单例模式需要变参构造函数,构造函数的参数个数需要支持变化
// 支持0~6个参数的单例模式实现

template <typename T>
class Singleton
{
public:
    // 支持0个参数的构造函数
    static T *Instance()
    {
        if (m_pInstance == nullptr)
            m_pInstance = new T();
        return m_pInstance;
    }

    // 支持1个参数的构造函数
    template <typename T0>
    static T *Instance(T0 arg0)
    {
        if (m_pInstance == nullptr)
            m_pInstance = new T(arg0);
        return m_pInstance;
    }

    // 支持2个参数的构造函数
    template <typename T0, typename T1>
    static T *Instance(T0 arg0, T1 arg1)
    {
        if (m_pInstance == nullptr)
            m_pInstance = new T(arg0, arg1);
        return m_pInstance;
    }

    // 支持3个参数的构造函数
    template <typename T0, typename T1, typename T2>
    static T *Instance(T0 arg0, T1 arg1, T2 arg2)
    {
        if (m_pInstance == nullptr)
            m_pInstance = new T(arg0, arg1, arg2);
        return m_pInstance;
    }

    // 支持4个参数的构造函数
    template <typename T0, typename T1, typename T2, typename T3>
    static T *Instance(T0 arg0, T1 arg1, T2 arg2, T3 arg3)
    {
        if (m_pInstance == nullptr)
            m_pInstance = new T(arg0, arg1, arg2, arg3);
        return m_pInstance;
    }

    // 支持5个参数的构造函数
    template <typename T0, typename T1, typename T2, typename T3, typename T4>
    static T *Instance(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
    {
        if (m_pInstance == nullptr)
            m_pInstance = new T(arg0, arg1, arg2, arg3, arg4);
        return m_pInstance;
    }

    // 支持6个参数的构造函数
    template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
    static T *Instance(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
    {
        if (m_pInstance == nullptr)
            m_pInstance = new T(arg0, arg1, arg2, arg3, arg4, arg5);
        return m_pInstance;
    }

    // 获取单例
    static T GetInstance()
    {
        if (m_pInstance == nullptr)
        {
            std::cout << "the instance is not init, please initialize the instance first" << std::endl;
            return nullptr;
        }
        return m_pInstance;
    }

    // 释放单例
    static void DestroyInstance()
    {
        delete m_pInstance;
        m_pInstance = nullptr;
    }

private:
    // 不允许赋值和复制
    Singleton(void);
    virtual ~Singleton(void);
    Singleton(const Singleton &);
    Singleton &operator=(const Singleton &);

    static T *m_pInstance;
};

template <class T>
T *Singleton<T>::m_pInstance = nullptr;

// test data
struct A
{
    A() {}
};

struct B
{
    B(int x) {}
};

struct C
{
    C(int x, double y) {}
};

int main(void)
{
    Singleton<A>::Instance();
    Singleton<B>::Instance(1);
    Singleton<C>::Instance(1, 3.14);

    Singleton<A>::DestroyInstance();
    Singleton<B>::DestroyInstance();
    Singleton<C>::DestroyInstance();

    return 0;
}

 

通过变参模板改进单例模式

#include <iostream>
#include <string>

template <typename T>
class Singleton
{
public:
    template <typename... Args>
    static T *Instance(Args &&...args)
    {
        if (m_pInstance == nullptr)
            m_pInstance = new T(std::forward<Args>(args)...);
        return m_pInstance;
    }

    // 获取单例
    static T *GetInstance()
    {
        if (m_pInstance == nullptr)
        {
            std::cout << "the instance is not init, please initialize the instance first" << std::endl;
            return nullptr;
        }
        return m_pInstance;
    }

    static void DestoryInstance()
    {
        delete m_pInstance;
        m_pInstance = nullptr;
    }

private:
    Singleton(void);
    virtual ~Singleton(void);
    Singleton(const Singleton &);
    Singleton &operator=(const Singleton &);
    static T *m_pInstance;
};

template <typename T>
T *Singleton<T>::m_pInstance = nullptr;

// test data
struct A
{
    A(const std::string &)
    {
        std::cout << "lvalue" << std::endl;
    }
    A(std::string &&x)
    {
        std::cout << "rvalue" << std::endl;
    }
};

struct B
{
    B(const std::string &)
    {
        std::cout << "lvalue" << std::endl;
    }
    B(std::string &&x)
    {
        std::cout << "rvalue" << std::endl;
    }
};

struct C
{
    C(int x, double y) {}
    void Fun() { std::cout << "test" << std::endl; }
};

int main(void)
{
    std::string str = "bb";

    // 创建A类型的单例
    Singleton<A>::Instance(str);

    // 创建B类型的单例
    Singleton<B>::Instance(std::move(str));

    // 创建C类型的单例
    Singleton<C>::Instance(1, 3.14);

    // 获取单例并调用单例对象的方法
    Singleton<C>::GetInstance()->Fun();

    // 释放单例
    Singleton<A>::DestoryInstance();
    Singleton<B>::DestoryInstance();
    Singleton<C>::DestoryInstance();
}

编译运行

 

 

标签:pInstance,Singleton,变参,arg0,Instance,单例,模板,构造函数
From: https://www.cnblogs.com/wangtianning1223/p/16636049.html

相关文章

  • JavaScript设计模式及代码实现——单例模式
    单例模式1定义保证一个类仅有一个实例,并提供一个访问它的全局访问点。2应用时机当一个类的实例被频繁使用,如果重复创建这个实例,会无端消耗资源。比如dialog弹......
  • 设计模式—模板方法模式(template)
         模板方法模式,我们来看一下定义:定义了一个算法的骨架,而将一些步骤延迟到子类中,模版方法使得子类可以在不改变算法结构的情况下,重新定义算法的步骤。我们来定......
  • 高精度模板
    赌一手今年CSP必考高精。加法:#include<bits/stdc++.h>usingnamespacestd;stringa,b;vector<int>add(vector<int>A,vector<int>B){if(A.size()<......
  • 模板——数据结构
    线段树维护区间最值以及满足最值的个数structSGT{ intmx[N<<2],tg[N<<2],su[N<<2]; #definemid((l+r)>>1) #definelc(u<<1) #definerc((u<<1)|1) voidbld(......
  • 最长上升子序列【模板】
     P1439【模板】最长公共子序列-洛谷|计算机科学教育新生态(luogu.com.cn)n^2的最长上升子序列解法#include<iostream>usingnamespacestd;intdp[1001][100......
  • 单例模式的介绍
     单例模式是设计模式中常用的设计模式之一,它提供一种创建对象的方式。这种模式仅涉及一个单一的类,该类负责创建自身的对象(下面称对象为实例),同时确保只有一个对象被创......
  • C++ 之函数模板
    C++之函数模板函数的参数类型不确定,这样就可以使用泛型。//类型参数化C++中称之为泛型编程--模板技术template<classT>//告诉编译器,下面如果出现T不要报错,T是......
  • 简单动态变量文本模板
    TemplateUtils工具类importlombok.experimental.UtilityClass;importorg.springframework.cglib.beans.BeanMap;importjava.util.*;importjava.util.regex.Matche......
  • Django入门到放弃之模板及标签
    1.django模板使用的两种方式#方式一 returnrender(request,'time.html',context={'current_date':str(now),'title':'lqzNB'})#方式二(页面静态化,提高网站并发量)......
  • 可变参数模板
    获取参数个数template<class...T>voidf(T...args){cout<<sizeof...(args)<<endl;//打印变参的个数}f();//0f(1,2);//2f(1,2.5,"......