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;  
}
相关推荐
霁月风1 小时前
设计模式——适配器模式
c++·适配器模式
jrrz08281 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
咖啡里的茶i2 小时前
Vehicle友元Date多态Sedan和Truck
c++
海绵波波1072 小时前
Webserver(4.9)本地套接字的通信
c++
@小博的博客2 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
爱吃喵的鲤鱼3 小时前
linux进程的状态之环境变量
linux·运维·服务器·开发语言·c++
7年老菜鸡3 小时前
策略模式(C++)三分钟读懂
c++·qt·策略模式
Ni-Guvara3 小时前
函数对象笔记
c++·算法
似霰4 小时前
安卓智能指针sp、wp、RefBase浅析
android·c++·binder
芊寻(嵌入式)4 小时前
C转C++学习笔记--基础知识摘录总结
开发语言·c++·笔记·学习