在c++11之前,我们写单例模式的时候会遇到一个问题,就是多种类型的单例可能需要创建多个类型的单例,主要是因为创建单例对象的构造函数无法统一,各个类型的形参不尽相同,导致我们不容易做一个所有类型都通用的单例。现在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, please initialize the instance first”);
return m_pInstance;
}
static void DestroyInstance() { delete m_pInstance; m_pInstance = nullptr; } private: Singleton(void); virtual ~Singleton(void); Singleton(const Singleton&); Singleton& operator = (const Singleton&); private: static T* m_pInstance; }; template <class T> T* Singleton<T>::m_pInstance = nullptr;
这个单例模式可以解决不同类型构造函数形参不尽相同的问题,真正意义上对所有类型都通用的单例模式。
/***********更新说明****************/
由于原来的接口中,单例对象的初始化和取值都是一个接口,可能会遭到误用,更新之后,讲初始化和取值分为两个接口,单例的用法为:先初始化,后面取值,如果中途销毁单例的话,需要重新取值。如果没有初始化就取值则会抛出一个异常。
增加Multiton的实现
#include <map>
include <memory>
using namespace std;
template < typename T, typename K = string>
class Multiton
{
public:
template<typename… Args>
static std::shared_ptr<T> Instance(const K& key, Args&&… args)
{
return GetInstance(key, std::forward<Args>(args)…);
}
template</span><typename... Args>
<span style="color: #0000ff;">static</span> std::shared_ptr<T> Instance(K&& key, Args&&<span style="color: #000000;">... args)
{
</span><span style="color: #0000ff;">return</span> GetInstance(key, std::forward<Args><span style="color: #000000;">(args)...);
}
private:
template<typename Key, typename… Args>
static std::shared_ptr<T> GetInstance(Key&& key, Args&&…args)
{
std::shared_ptr<T> instance = nullptr;
auto it = m_map.find(key);
if (it == m_map.end())
{
instance = std::make_shared<T>(std::forward<Args>(args)…);
m_map.emplace(key, instance);
}
else
{
instance = it->second;
}
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> instance;
}
private:
Multiton(void);
virtual ~Multiton(void);
Multiton(const Multiton&);
Multiton& operator = (const Multiton&);
private:
static map<K, std::shared_ptr<T>> m_map;
};
template <typename T, typename K>
map<K, std::shared_ptr<T>> Multiton<T, K>::m_map;