C++带模板的单例模式自动释放——内部类

实现一个模板形式的单例类,要求对于任意类型的类经过Singleton的处理之后,都能获取一个单例对象,并且可以传递任意参数(传递任意参数就是要用到可变模板参数)

单例模式

一个类只能创建一个实例,

c++ 复制代码
#include <iostream>  
 
class Singleton
{
public:
    static Singleton* getInstance()
    {
        if(nullptr == _pInstance){
            _pInstance = new Singleton();
        }
        return _pInstance;
    }
private:
    Singleton()
    {
    }
    ~Singleton()
    {
    }
private:
    static Singleton* _pInstance;
};
Singleton* Singleton::_pInstance = nullptr; 
//静态数据成员在类外初始化,对于头文件和实现文件的形式,还应将静态数据成员放在实现文件中进行初始化,避免多次定义的问题

模板形式的单例类 + 可变参数

c++ 复制代码
#include <iostream>  

template<typename T>
class Singleton
{
public:
    template <typename ...Args> //当参数个数和类型不同时,用可变参数模板
    static T* getInstance(Args ...args)
    {
        if(nullptr == _pInstance){
            _pInstance = new T(args...);
        }
        return _pInstance;
    }
private:
    Singleton()
    {
    }
    ~Singleton()
    {
    }
private:
    static T* _pInstance;
};
template <typename T>
T* Singleton<T>::_pInstance = nullptr;

单例模式自动释放------内部类

c++ 复制代码
#include <iostream>  
  
using std::cout;  
using std::endl;  
  
template<typename T>   
class Singleton  
{  
public:  
    template <typename ...Args>//参数的个数和类型不同,可变模板参数  
    static T* getInstance(Args ...args)  
    {  
        if(nullptr == _pInstance)  
        {  
            _pInstance = new T(args...); 
            //因为new出来的和singleton中传的模板类型相同,是T类型的
        }  
        return _pInstance;  
    }  
  
private:  
    class AutoRelease  
    {  
    public:  
        AutoRelease()  
        {  
            cout << "AutoRelease()" <<endl;  
        }  
  
        ~AutoRelease()  
        {  
            cout << "~AutoRelease()" <<endl;  
            if(_pInstance)  
            {  
                delete _pInstance;  
                _pInstance = nullptr;  
            }  
        }  
    };  
private:  
    Singleton()  
    {  
        cout << "Singleton()" << endl;  
    }  
    ~Singleton()  
    {  
        cout << "~Singleton()" << endl;  
    }  
private:  
    static T* _pInstance;  
    static AutoRelease _ar;  
};    
  
template <typename T>  
T* Singleton<T>::_pInstance = nullptr;  
  
template <typename T>  
typename Singleton<T>::AutoRelease Singleton<T>::_ar;  
  

# 测试
```c++

class Point  
{  
public:  
    Point(int ix = 0, int iy = 0)  
    : _ix(ix)  
    , _iy(iy)  
    {  
        cout << "Point(int ix = 0, int iy = 0)" << endl;  
    }  
  
    void print()const  
    {  
        cout << "(" << _ix  
             << "," << _iy  
             << ")" << endl;  
    }  
    ~Point()  
    {  
        cout << "~point()" <<endl;  
    }  
private:  
    int _ix;  
    int _iy;  
};
void test()  
{  
    Point *pt1 = Singleton<Point>::getInstance(1,2);  
    Point *pt2 = Singleton<Point>::getInstance(3,4);  
    pt1->print();  
    pt2->print();  
}  
  
int main(int argc, char* argv[])  
{  
    test();  
    return 0;  
}

测试结果:AutoRelease()及其析构函数没有执行 原因:_ar没有初始化为具体的值。没有写成模板的时候,_ar作为静态数据成员进行初始化。 程序结束时,生命周期结束,执行自己的析构函数的同时,带着将_pInstance销毁。此时,在main执行之前,静态数据成员已完成初始化 但有模板后,在main执行前,静态数据成员还未完成初始化。 在执行main函数、执行test后,才会将T推导成Point。在进到main之前,_ar还是抽象的,没有实例化

解决:在test执行getinstance时,就将_ar实例化(为防止_ar多次实例化,将到if语句内)

最终

c++ 复制代码
#include <iostream>  
  
using std::cout;  
using std::endl;  
  
template<typename T>   
class Singleton  
{  
public:  
    template <typename ...Args>//参数的个数和类型不同,可变模板参数  
    static T* getInstance(Args ...args)  
    {  
        if(nullptr == _pInstance)  
        {  
            _ar; 
            _pInstance = new T(args...);  
        }  
        return _pInstance;  
    }  
  
private:  
    class AutoRelease  
    {  
    public:  
        AutoRelease()  
        {  
            cout << "AutoRelease()" <<endl;  
        }  
  
        ~AutoRelease()  
        {  
            cout << "~AutoRelease()" <<endl;  
            if(_pInstance)  
            {  
                delete _pInstance;  
                _pInstance = nullptr;  
            }  
        }  
    };  
private:  
    Singleton()  
    {  
        cout << "Singleton()" << endl;  
    }  
    ~Singleton()  
    {  
        cout << "~Singleton()" << endl;  
    }  
private:  
    static T* _pInstance;  
    static AutoRelease _ar;  
};    
  
template <typename T>  
T* Singleton<T>::_pInstance = nullptr;  
  
template <typename T>  
typename Singleton<T>::AutoRelease Singleton<T>::_ar;  
  
class Point  
{  
public:  
    Point(int ix = 0, int iy = 0)  
    : _ix(ix)  
    , _iy(iy)  
    {  
        cout << "Point(int ix = 0, int iy = 0)" << endl;  
    }  
  
    void print()const  
    {  
        cout << "(" << _ix  
             << "," << _iy  
             << ")" << endl;  
    }  
    ~Point()  
    {  
        cout << "~point()" <<endl;  
    }  
private:  
    int _ix;  
    int _iy;  
};  
void test()  
{  
    Point *pt1 = Singleton<Point>::getInstance(1,2);  
    Point *pt2 = Singleton<Point>::getInstance(3,4);  
    pt1->print();  
    pt2->print();  
}  
  
int main(int argc, char* argv[])  
{  
    test();  
    return 0;  
}
相关推荐
麻辣韭菜2 小时前
网络基础 【HTTP】
网络·c++·http
阿史大杯茶2 小时前
Codeforces Round 976 (Div. 2 ABCDE题)视频讲解
数据结构·c++·算法
转调2 小时前
每日一练:地下城游戏
开发语言·c++·算法·leetcode
wdxylb3 小时前
使用C++的OpenSSL 库实现 AES 加密和解密文件
开发语言·c++·算法
CSP126364 小时前
特别节目————集训总结
c++
程序猿阿伟4 小时前
《C++游戏人工智能开发:开启智能游戏新纪元》
c++·人工智能·游戏
一线青少年编程教师4 小时前
线性表三——队列queue
数据结构·c++·算法
C4 小时前
C++_智能指针详解
开发语言·c++
qinzechen4 小时前
分享几个做题网站------学习网------工具网;
java·c语言·c++·python·c#
丶Darling.5 小时前
代码随想录 | Day26 | 二叉树:二叉搜索树中的插入操作&&删除二叉搜索树中的节点&&修剪二叉搜索树
开发语言·数据结构·c++·笔记·学习·算法