【C++】單例模式之C++實現
阿新 • • 發佈:2018-12-26
單例模式的概念
只允許一個產生一個物件的類單例模式的實現方法
1.單例類保證全域性只有唯一一個自行建立的例項物件2.單例類提供獲取這個唯一例項的介面
單例模式的優缺點
優點
(1)阻止其他度物件例項化自己的副本,保證所有訪問唯一性(2)類控制了例項化的過程,所以可以靈活的更改例項化的過程
缺點
(1)每次都需要檢查是否物件已經生成,造成些微的開銷(2)使用單例物件時,開發人員可能會意外發現自己無法例項化該類
單例模式的分類
懶漢模式(適用於各種場景)
在需要的時候建立物件懶漢模式需要加入synchronized才可以保證執行緒安全
餓漢模式(在某些場景下受到限制)
在main函式開始的時候即建立物件餓漢模式是執行緒安全的
程式碼實現
懶漢模式的實現
普通版本
class SingleTon { public: static SingleTon* GetInstance()//獲取物件例項的唯一介面 { if (_inst == NULL) { _inst = new SingleTon; } return _inst; } void Print() { cout << "SingleTon : " << _a << endl; } private: SingleTon()//防止建構函式建立物件 :_a(0) {} SingleTon& operator=(const SingleTon&) = delete; SingleTon(const SingleTon&) = delete; int _a; static SingleTon* _inst;//指向例項化的指標定義成靜態成員 }; SingleTon* SingleTon::_inst = NULL;
執行緒安全版本
加入RAII機制,避免死鎖的出現
class SingleTon { public: static SingleTon* GetInstance()//獲取物件例項的唯一介面 { if (NULL == _inst)//只有在建立例項的時候才進行加鎖提高效率 { lock_guard<mutex>lock(_mtx); if (_inst == NULL) { _inst = new SingleTon; } } return _inst; } void Print() { cout << "SingleTon : " << _a << endl; } private: SingleTon()//防止建構函式建立物件 :_a(0) {} SingleTon& operator=(const SingleTon&) = delete; SingleTon(const SingleTon&) = delete; int _a; static SingleTon* _inst;//指向例項化的指標定義成靜態成員 static mutex _mtx;//保證安全的互斥鎖 }; SingleTon* SingleTon::_inst = NULL; mutex SingleTon::_mtx;
記憶體柵欄技術&單例物件的釋放
新增雙檢查機制來提高效率 新增記憶體柵欄技術來防止由於提升效率而打亂執行的順序 對單例模式的釋放,下面這種方法是有問題的 最好是呼叫atexit回撥機制,在main函式結束完畢後再進行釋放class SingleTon
{
public:
static SingleTon* GetInstance()//獲取物件例項的唯一介面
{
if (NULL == _inst)//只有在建立例項的時候才進行加鎖提高效率
{
lock_guard<mutex>lock(_mtx);
if (_inst == NULL)
{
SingleTon* tmp = new SingleTon;
MemoryBarrier();//記憶體柵欄技術
_inst = tmp;
}
}
return _inst;
}
void Print()
{
cout << "SingleTon : " << _inst << endl;
}
static void DellInstance()
{
lock_guard<mutex>lock(_mtx);
if (_inst)
{
cout << "delete " << endl;
delete _inst;
_inst = NULL;
}
}
private:
SingleTon()//防止建構函式建立物件
:_a(0)
{}
SingleTon& operator=(const SingleTon&) = delete;
SingleTon(const SingleTon&) = delete;
int _a;
static SingleTon* _inst;//指向例項化的指標定義成靜態成員
static mutex _mtx;//保證安全的互斥鎖
};
SingleTon* SingleTon::_inst = NULL;
mutex SingleTon::_mtx;
餓漢模式的實現
簡潔,高效,不用加鎖
但是在特定情況下會出現問題實現方法1
class Singleton
{
public:
static Singleton& GetInstance()
{
assert(_inst);
return *_inst;
}
void Print()
{
cout << "Singleton : " << _inst << endl;
}
private:
Singleton()
:_a(0)
{}
int _a;
Singleton& operator=(const Singleton&) = delete;
Singleton(const Singleton&) = delete;
static Singleton* _inst;
};
Singleton* Singleton::_inst = new Singleton;
實現方法2
class Singleton
{
public:
static Singleton& GetInstance()
{
static Single _inst;
return *_inst;
}
void Print()
{
cout << "Singleton : " << _inst << endl;
}
private:
Singleton()
:_a(0)
{}
int _a;
Singleton& operator=(const Singleton&) = delete;
Singleton(const Singleton&) = delete;
static Singleton* _inst;
};
Singleton* Singleton::_inst = NULL;