亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

單例模式簡介

發布時間:2020-07-03 12:19:31 來源:網絡 閱讀:369 作者:duanjiatao 欄目:編程語言

什么是設計模式

設計模式代表了最佳實踐,是軟件開發過程中面臨一般問題的解決方案。

設計模式是一套被反復使用、經過分類、代碼設計總結的經驗。

單例模式

單例模式也叫單件模式。Singleton是一個非常常用的設計模式,幾乎所有稍微大一些的程序都會使用到它,所以構建一個線程安全并且高效的Singleton很重要。

1. 單例類保證全局只有一個唯一實例對象。

2. 單例類提供獲取這個唯一實例的接口。

怎樣設計一個單例模式


實現一(不考慮線程安全)

class Singleton
{
public:
// 獲取唯一對象實例的接口函數
	static Singleton* GetInstance()
	{
		if(_sInstance == NUL)
		{
			if (_sInstance == NULL)
			{
				_sInstance = new Singleton();
			}
		}
		return _sInstance;
	}
// 刪除實例對象
	static void DelInstance()
	{
		if (_sInstance)
		{
			delete _sInstance;
			_sInstance = NULL;
		}
	}
	void Print()
	{
		cout<<_data<<endl;
	}
private:
	// 構造函數定義為私有,限制只能在類內創建對象
	Singleton()
	:_data(0)
	{}
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);
	// 指向實例的指針定義為靜態私有,這樣定義靜態成員函數獲取對象實例
	static Singleton* _sInstance;
	// 單例類里面的數據
	int _data;
};
Singleton* Singleton::_sInstance = NULL;

void TestSingleton()
{
	Singleton::GetInstance()->Print();
	Singleton::DelInstance();
}

實現二

線程安全的單例 -- (懶漢模式-- lazy loading)

ps: 下面部分的加鎖使用了C++11庫的互斥鎖
class Singleton
{
public:
	// 獲取唯一對象實例的接口函數
	static Singleton* GetInstance()
	{
	// 使用雙重檢查,提高效率,避免高并發場景下每次獲取實例對象都進行加鎖
		if (_sInstance == NULL)
		{
			std::lock_guard<std::mutex> lck(_mtx);
			if (_sInstance == NULL)
			{
				// tmp = new Singleton()分為以下三個部分
				// 1.分配空間 2.調用構造函數 3.賦值
				// 編譯器編譯優化可能會把2和3進行指令重排,這樣可能會導致
				// 高并發場景下,其他線程獲取到未調用構造函數初始化的對象
				// 以下加入內存柵欄進行處理,防止編譯器重排柵欄后面的賦值
				// 到內存柵欄之前
				Singleton* tmp = new Singleton();
				MemoryBarrier();
				_sInstance = tmp;
			}
		}
		return _sInstance;
	}
	// 刪除實例對象
	static void DelInstance()
	{
		std::lock_guard<std::mutex> lck(_mtx);
		if (_sInstance)
		{
			delete _sInstance;
			_sInstance = NULL;
		}
	}
	void Print()
	{
	cout<<_data<<endl;
	}
private:
	// 構造函數定義為私有,限制只能在類內創建對象
	Singleton()
	:_data(0)
	{}
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);
	// 指向實例的指針定義為靜態私有,這樣定義靜態成員函數獲取對象實例
	static Singleton* _sInstance;
	// 保證線程安全的互斥鎖
	static mutex _mtx;
	// 單例類里面的數據
	int _data;
};
Singleton* Singleton::_sInstance = NULL;
mutex Singleton::_mtx;

void TestSingleton()
{
Singleton::GetInstance()->Print();
Singleton::DelInstance();
}

實現三

線程安全的單例 -- (餓漢模式--簡潔、高效、不用加鎖、但是在某些場景下會有缺陷)

方法1

// 方式一
class Singleton
{
public:
	// 獲取唯一對象實例的接口函數
	static Singleton* GetInstance()
	{
		static Singleton sInstance;
		return &sInstance;
	}
	void Print()
	{
		cout<<_data<<endl;
	}
private:
	// 構造函數定義為私有,限制只能在類內創建對象
	Singleton()
	:_data(0)
	{}
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);
	// 單例類里面的數據
	int _data;
};

void TestSingleton()
{
	Singleton::GetInstance()->Print();
}

方法2

// 方式二
class Singleton
{
public:
	// 獲取唯一對象實例的接口函數
	static Singleton* GetInstance()
	{
		assert(_sInstance);
		return _sInstance;
	}
	// 刪除實例對象
	static void DelInstance()
	{
		if (_sInstance)
		{
			delete _sInstance;
			_sInstance = NULL;
		}
	}
	void Print()
	{
		cout << _data << endl;
	}
private:
	// 構造函數定義為私有,限制只能在類內創建對象
	Singleton()
	:_data(0)
	{}
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);
	// 指向實例的指針定義為靜態私有,這樣定義靜態成員函數獲取對象實例
	static Singleton* _sInstance;
	// 單例類里面的數據
	int _data;
};
Singleton* Singleton::_sInstance = new Singleton;

void TestSingleton()
{
	Singleton::GetInstance()->Print();
	Singleton::DelInstance();
}

帶RAII GC 自動回收實例對象的方式

class Singleton
{
public:
	// 獲取唯一對象實例的接口函數
	static Singleton* GetInstance()
	{
		assert(_sInstance);
		return _sInstance;
	}
	// 刪除實例對象
	static void DelInstance()
	{
		if (_sInstance)
		{
			delete _sInstance;
			_sInstance = NULL;
		}
	}
	void Print()
	{
		cout << _data << endl;
	}
	class GC
	{
		public:
		~GC()
		{
			cout << "DelInstance()"<<endl;
			DelInstance();
		}
	};
private:
	// 構造函數定義為私有,限制只能在類內創建對象
	Singleton()
	:_data(0)
	{}
	// 指向實例的指針定義為靜態私有,這樣定義靜態成員函數獲取對象實例
	static Singleton* _sInstance;
	// 單例類里面的數據
	int _data;
};
// 靜態對象在main函數之前初始化,這時只有主線程運行,所以是線程安全的。
Singleton* Singleton::_sInstance = new Singleton;
// 使用RAII,定義全局的GC對象釋放對象實例
Singleton::GC gc;
void TestSingleton()
{
	Singleton::GetInstance()->Print();
}

由于程序在結束的時候,系統會自動析構所有的全局變量,實際上,系統也會析構所有類的靜態成員變量,就像這些靜態變量是全局變量一樣。我們知道,靜態變量和全局變量在內存中,都是存儲在靜態存儲區的,所以在析構時,是同等對待的。


單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介單例模式簡介

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

吴川市| 随州市| 专栏| 儋州市| 顺平县| 永济市| 壶关县| 汾阳市| 和平县| 平安县| 南开区| 綦江县| 鄂伦春自治旗| 威远县| 溧水县| 台东市| 仪陇县| 女性| 赤水市| 宁武县| 贵溪市| 龙山县| 多伦县| 姜堰市| 增城市| 陕西省| 磐安县| 郑州市| 敦化市| 绥江县| 庐江县| 睢宁县| 历史| 大洼县| 阜阳市| 赞皇县| 西吉县| 星子县| 大田县| 鹤岗市| 独山县|