在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;