參考
C++ 單例模式總結與剖析
什麼是單例
目的:創建類中的對象,並且保證只有一個對象實例。
單例類內部實現只生成一個唯一實例,同時他提供一個靜態的getInstance()
工廠方法讓外部可以訪問他的唯一實例。
外部不能直接創建該類的對象,因爲默認構造和拷貝函數設計爲私有,只能通過getInstance方法來得到這個對象。
特點:單例 Singleton 是設計模式的一種,其特點是隻提供唯一一個類的實例,具有全局變量的特點,在任何位置都可以通過接口獲取到那個唯一實例;
具體使用場景
- 設備管理器,系統中可能有多個設備,但是隻有一個設備管理器,用於管理設備驅動;
- 數據池,用來緩存數據的數據結構,需要在一處寫,多處讀取或者多處寫,多處讀取;
單例模式案例
主席模式
目的:爲了讓類中只有一個實例,實例不需要自己釋放
步驟:
- 默認構造和拷貝構造私有化
- 內部維護一個私有唯一對象指針
- 對外提供getInstance方法來訪問這個指針
#include <iostream>
using namespace std;
class ChairMan
{
private:
//構造函數私有化
ChairMan()
{
cout << "構造函數" << endl;
}
//拷貝構造私有化
ChairMan(const ChairMan &c)
{
cout << "拷貝構造" << endl;
}
// 創建一個靜態的*singleMan對象
static ChairMan *singleMan; //內部維護一個指針
public:
//對外暴露藉口,提供方法返回實例對象
static ChairMan* getInstance()
{
return singleMan; //私有的對象指針返回
}
};
//static 成員變量,內部定義外部實現
ChairMan* ChairMan::singleMan = new ChairMan;
int main()
{
ChairMan *cm1 = ChairMan::getInstance(); //不能有其他方式創建該類的實例。
}
打印機模式
#include <iostream>
using namespace std;
class Printer
{
private:
Printer() { m_Count = 0; };
Printer(const Printer &p){};
static Printer *singlePrinter;
int m_Count;
public:
static Printer *getInstance()
{
return singlePrinter;
}
void printText(string text)
{
cout << text << endl;
m_Count++;
cout << "打印機使用次數爲: " << m_Count << endl;
}
};
Printer *Printer::singlePrinter = new Printer;
void test1()
{
Printer *printer = Printer::getInstance();
printer->printText(" 報告1");
printer->printText(" 報告2");
printer->printText(" 報告3");
Printer *printer2 = Printer::getInstance();
printer->printText(" 報告1");
printer->printText(" 報告2");
if (printer == printer2)
{
cout << "printer 等於 printer2 " << endl;
}
}
int main()
{
test1();
Printer *printer = Printer::getInstance();
printer->printText(" 報告1");
}
/*
報告1
打印機使用次數爲: 1
報告2
打印機使用次數爲: 2
報告3
打印機使用次數爲: 3
報告1
打印機使用次數爲: 4
報告2
打印機使用次數爲: 5
printer 等於 printer2
報告1
打印機使用次數爲: 6
*/
通過該代碼我們發現, 使用單例模式,我們創建的是一個全局實例,全局僅有唯一實例,即使我們再getInstance, 他拿到的還是全局唯一那個實例。
這也就達到了我們的需求:有些對象我們只需要一個,比如:線程池、緩存、對話框、處理偏好設置、註冊表等對象,這些對象只能有一個實例,如果製造出多個實例,就會導致很多問題產生
最推薦的懶漢式單例代碼
#include <iostream>
class Singleton
{
public:
~Singleton(){
std::cout<<"destructor called!"<<std::endl;
}
Singleton(const Singleton&)=delete;
Singleton& operator=(const Singleton&)=delete;
static Singleton& get_instance(){
static Singleton instance;
return instance;
}
private:
Singleton(){
std::cout<<"constructor called!"<<std::endl;
}
};
int main(int argc, char *argv[])
{
Singleton& instance_1 = Singleton::get_instance();
Singleton& instance_2 = Singleton::get_instance();
return 0;
}
/*
constructor called!
destructor called!
*/