C++學習筆記 —— 單例模式


參考
C++ 單例模式總結與剖析

什麼是單例

目的:創建類中的對象,並且保證只有一個對象實例。

單例類內部實現只生成一個唯一實例,同時他提供一個靜態的getInstance()工廠方法讓外部可以訪問他的唯一實例。
外部不能直接創建該類的對象,因爲默認構造和拷貝函數設計爲私有,只能通過getInstance方法來得到這個對象。

特點:單例 Singleton 是設計模式的一種,其特點是隻提供唯一一個類的實例,具有全局變量的特點,在任何位置都可以通過接口獲取到那個唯一實例;

具體使用場景

  1. 設備管理器,系統中可能有多個設備,但是隻有一個設備管理器,用於管理設備驅動;
  2. 數據池,用來緩存數據的數據結構,需要在一處寫,多處讀取或者多處寫,多處讀取;

單例模式案例

主席模式

目的:爲了讓類中只有一個實例,實例不需要自己釋放
步驟:

  1. 默認構造和拷貝構造私有化
  2. 內部維護一個私有唯一對象指針
  3. 對外提供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!
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章