实现一个模板形式的单例类,要求对于任意类型的类经过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;
}