定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
类图:
C++11前,实现一个通用的泛型单例模式,支持0~3个参数的单例如下:
template <typename T>
class Singleton
{
public:
// 支持0个参数的构造函数
static T* Instance()
{
if (m_pInstance == null)
m_pInstance = new T();
return m_pInstance;
}
// 支持1个参数的构造函数
template<typename T0>
static T* Instance(T0 arg0)
{
if (m_pInstance == null)
m_pInstance = new T(arg0);
return m_pInstance;
}
// 支持2个参数的构造函数
template<typename T0,typename T1>
static T* Instance(T0 arg0, T1 arg1)
{
if (m_pInstance == null)
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 == null)
m_pInstance = new T(arg0, arg1, arg2);
return m_pInstance;
}
// 获取单例
static T* GetInstance()
{
if (m_pInstance == null)
throw std::logic_error("the instance is not init");
return m_pInstance;
}
// 释放单例
static void DestroyInstance()
{
delete m_pInstance;
m_pInstance = nullptr;
}
private:
Singleton();
virtual ~Singleton();
Singleton(const Singleton&);
Singleton& operator = (const Singletion&);
static T* m_pInstance;
};
template <class T> T* Singleton<T>::m_pInstance = nullptr;
测试代码如下:
struct A
{
A() {}
};
struct B
{
B(int x) {}
};
struct C
{
C(int x, double y) {}
};
int main()
{
Singleton<A>::Instance();
Singleton<B>::Instance(1);
Singleton<C>::Instance(1, 2);
Singleton<A>::DestroyInstance();
Singleton<B>::DestroyInstance();
Singleton<C>::DestroyInstance();
}
这个单例中的函数有很多重复定义,且当函数参数超过3个时,不得不再增加构造函数定义。
利用C++11的可变参数,可以消除这种重复,同时支持完美转发。既增加了灵活性又提高了性能。
C++11可变参数模板的单例:
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)
{
throw std::logic_error("the instance is not init");
}
return m_pInstance;
}
// 销毁单例
static void DestroyInstance()
{
delete m_pInstance;
m_pInstance = nullptr;
}
private:
Singleton();
virtual ~Singleton();
Singleton(const Singleton&);
Singleton& operator = (const Singleton&);
static T* m_pInstance;
};
template <class T> T* Singleton<T>::m_pInstance = nullptr;
测试代码:
#include <iostream>
#include <string>
using namespace std;
struct A
{
A(const string&) { cout << "lvalue" << endl; };
A(string&& x) { cout << "rvalue" << endl; };
};
struct B
{
B(const string&) { cout << "lvalue" << endl; };
B(string&& x) { cout << "rvalue" << endl; };
};
struct C
{
C(int x, int y) {}
void Fun() { cout << "test" << endl; }
};
int main()
{
string str = "xxx";
Singleton<A>::Instance(str);
Singleton<B>::Instance(std::move(str));
Singleton<C>::Instance(1, 2);
Singleton<C>::GetInstance->Fun();
Singleton<A>::DestroyInstance();
Singleton<B>::DestroyInstance();
Singleton<C>::DestroyInstance();
return 0;
}
输出结果:
lvalue
rvalue
test