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;  
}
相关推荐
LXS_3571 天前
Day 18 C++提高 之 STL常用容器(string、vector、deque)
开发语言·c++·笔记·学习方法·改行学it
deng-c-f1 天前
Linux C/C++ 学习日记(53):原子操作(二):实现shared_ptr
开发语言·c++·学习
一个不知名程序员www1 天前
算法学习入门---结构体和类(C++)
c++·算法
墨雪不会编程1 天前
C++ string 详解:STL 字符串容器的使用技巧
java·开发语言·c++
yangpipi-1 天前
《C++并发编程实战》第5章 C++内存模型和原子操作
android·java·c++
SunkingYang1 天前
MFC进程间消息通信深度解析:SendMessage、PostMessage与SendNotifyMessage的底层实现与实战指南
c++·mfc·共享内存·通信·postmessage·sendmessage·进程间
XFF不秃头1 天前
力扣刷题笔记-旋转图像
c++·笔记·算法·leetcode
王老师青少年编程1 天前
csp信奥赛C++标准模板库STL案例应用3
c++·算法·stl·csp·信奥赛·lower_bound·标准模版库
Tim_101 天前
【C++入门】04、C++浮点型
开发语言·c++
hkNaruto1 天前
【C++】记录一次C++程序编译缓慢原因分析——滥用stdafx.h公共头文件
开发语言·c++