一、單例模式優點及適用場景
單例模式特點:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點,該實例被所有程序模塊共享。
實現策略:
- 1.單例模式的類只提供私有的構造函數
- 2.類定義中含有一個該類的靜態私有對象
- 3.該類提供了一個靜態的公有的函數用於創建或獲取它本身的靜態私有對象
實現方法:餓漢式單例(開始即初始化單例對象)、懶漢式單例(需要時再實例化單例對象)
優點:
- 1.在內存中只有一個對象,節省內存空間
- 2.避免頻繁的創建銷燬對象,可以提高性能
- 3.避免對共享資源的多重佔用
- 4.可以全局訪問
適用場景:
- 1.需要頻繁實例化然後銷燬的對象
- 2.創建對象耗時過多或者耗資源過多,但又經常用到的對象
- 3.有狀態的工具類對象
- 4.頻繁訪問數據庫或文件的對象
- 5.以及其他要求只有一個對象的場景
二、餓漢模式
特點:開始即初始化單例對象
優點:不用擔心多線程問題
缺點:可能程序沒有用到該單例對象,造成浪費
#include <iostream>
using namespace std;
class Singleton {
public:
static Singleton* GetInstance() {
return &singleton_;
}
private:
Singleton(){}
static Singleton singleton_;
};
Singleton Singleton::singleton_;
int main() {
auto p1 = Singleton::GetInstance();
auto p2 = Singleton::GetInstance();
bool result = (p1 == p2);
cout << result << endl;
return 0;
}
三、懶漢模式
特點:需要時再實例化單例對象
優點:在不使用到單例對象時不會造成資源浪費
“缺點”:需要考慮多線程問題,稍微複雜一點(加鎖解決)
#include <iostream>
#include <mutex>
using namespace std;
class Singleton {
public:
static Singleton* GetInstance() {
//判斷是否已存在實例
if (p_singleton_ == nullptr) {
//加鎖
lock_guard<mutex> lock(mux_);
//可能兩個線程同時通過第一次檢查,一個線程獲得鎖,可能另外一個線程已經實例化
if (p_singleton_ == nullptr) {
p_singleton_ = new Singleton();
}
}
return p_singleton_;
}
private:
Singleton(){}
static Singleton* p_singleton_;
static mutex mux_;
};
mutex Singleton::mux_;
Singleton *Singleton::p_singleton_ = nullptr;
int main() {
auto p1 = Singleton::GetInstance();
auto p2 = Singleton::GetInstance();
bool result = (p1 == p2);
cout << result << endl;
return 0;
}