1. 程式人生 > >用c++11做單例模式

用c++11做單例模式

    做個工程上能用的單例模式,不僅要支援多執行緒,也要支援多引數傳遞,也要支援餓漢和懶漢兩種模式,用了下c++11的call_once, lamda表示式,可變引數模板和forward的轉發,程式碼如下:

#include <iostream>
#include <mutex>
using namespace std;
template<class T>
class Singleton
{
public:
	template<class... Params>
	static void init(Params&&... params)
	{
		if(ins == NULL)
			ins=new T(std::forward<Params>(params)...);
	}
	static T* get()
	{
		if(ins == NULL)
		{
			cout<<"please init first."<<endl;
			return ins;
		}
		return ins;
	}

	template<class... Params>
	static T* getAndInit(Params&&... params)
	{
		static std::once_flag oc;//用於call_once的區域性靜態變數
   		std::call_once(oc, [&]{ins = new T(std::forward<Params>(params)...);});
    	        return ins;
	}
	static void destroy()
	{
		delete ins;
		ins=NULL;
	}
private:
	Singleton();
	virtual ~Singleton();
	Singleton(const Singleton& s);
	Singleton& operator=(const Singleton& s);
	static T* ins;
};
template<class T> T* Singleton<T>::ins=NULL;

其中init和get分離的是餓漢模式,在多執行緒程式中,潛在出現競爭的是new的地方,將init放到一個安全的地方,比如主程序的初始化部分,可以避免競爭。

getAndInit是典型的懶漢模式,即在get的時候檢查初始化,傳統的處理方法是double check+記憶體柵欄,不過既然c++11提供了call_once這麼適合單例的操作,不用就可惜了,call_once的實際工作用的是lamda表示式。

template<class... Params> 比傳統的template多了3個點,實現了可變引數模板,forward直接把可變的引數完美轉發了。

Singleton的private部分是為了禁止構造,析構,拷貝構造和賦值,多說一句virtual修飾析構,是為了呼叫派生類和基類的解構函式,應對了動態繫結,預防了記憶體洩漏。

在函式外的ins賦值為NULL的部分,完成對ins的定義,這裡需要在template之後明確的指定型別為T*。

附一個測試例子,註釋掉的部分是測試餓漢的部分。

struct A
{
	int a;
	A(int val)
	{
		a=val;
		cout<<"A is construct"<<endl;
	}
};
int main()
{
	// Singleton<A>::init(21);
	// A* test1=Singleton<A>::get();
	// cout<<test1<<endl;
	// A* test2=Singleton<A>::get();
	A* test1=Singleton<A>::getAndInit(32);
	A* test2=Singleton<A>::getAndInit(34);
	cout<<test1<<endl;
	cout<<test2<<endl;
	cout<<test2->a<<endl;
	Singleton<A>::destroy();
	return 0;
}

編譯的方法是:

g++ test.cc -o test -std=c++11 -pthread
注意用到了call_once這個函式,所以編譯的時候需要pthread。

相關推薦

c++11模式

    做個工程上能用的單例模式,不僅要支援多執行緒,也要支援多引數傳遞,也要支援餓漢和懶漢兩種模式,用了下c++11的call_once, lamda表示式,可變引數模板和forward的轉發,程式碼如下:#include <iostream> #include

c++的模式c++11模式的優化

on() end per let namespace lease 是否 存在 建立 單例模式 單例模式,可以說設計模式中最常應用的一種模式了,據說也是面試官最喜歡的題目。但是如果沒有學過設計模式的人,可能不會想到要去應用單例模式,面對單例模式適用的情況,可能會優先考慮使用全

C++11改進模式

我們在寫單例模式的時候會遇到一個問題,就是多種型別的單例可能需要建立多個型別的單例,主要是因為建立單例物件的建構函式無法統一,各種型別的形參不盡相同,導致我們不容易做一個所有型別都通過的單例。現在C++

c++11模式

以往用C++實現一個單例模式需要寫以下程式碼: 1 class CSingleton 2 { 3 private: 4 CSingleton() //建構函式是私有的 5 { 6 } 7 static CSingleton

C++再論模式

proc .text pro auto -c com hide lock views #include <iostream> #include <windows.h> #include <mutex> std::mut

c#之使用模式實現數據庫連接

strings instance ssl div lock config onf 鎖定 特殊 1、使用程序集Oracle.ManagedDataAccess.dll using Oracle.ManagedDataAccess.Client; using System.Co

C#淺談模式

第一次寫部落格,寫的不好休怪哈。 版本1:最簡單的單例模式 方法一: public class MySingleton { private MySingleton() //建構函式,注意private {

C#中的模式

單例模式現在有二種,第一個是餓漢模式,第二個是懶漢模式。筆者將去實現這2個例子,然後分析它們的優缺點。1.餓漢模式using System;namespace DesignMode{    class SingletonMode    {        public stat

C++單體類 || 模式 的實現

單件模式是設計模式中最簡單的模式了。     定義: 確保一個類只有一個例項,並提供一個全域性的訪問點。 把一個類設計成自己管理的一個單獨例項,同時避免其他類再自行生成例項(所以建構函式用protect或privite) 也提供全域性的訪問點。public函式 一、

c++中的 模式(singleton)和雙檢測鎖(Double-Checked Locking)

今天學習了一下c++中的singleton。google了一篇論文C++ and the Perils of Double-Checked Locking。大名鼎鼎的Scott Meyers寫的。論文使用c++講解,看了之後受益匪淺。 巧的是,讀完之後剛好看見http://

C++實現一個模式(懶漢與餓漢)

單例模式的特點: 1、一個類只能有一個例項。 2、一個類必須自己建立自己的唯一例項。 3、一個類必須給所有其他物件提供這一例項。 單例模式的實現: 1、將建構函式宣告為private防止被外部

C++中的模式及按需釋放模型(五)

四、多執行緒安全的通用單例類例項獲取器 例子工程的名稱是SingletonThreadSafeInstanceGetter。 剛開始寫本文時,本沒有想實現多執行緒版本,主觀上以為同通常的單例模式一樣,多個多執行緒同步就可以了,很簡單,讓讀者自己開發就好了,不過後來真正去思考

C++深入理解模式詳解

作者:知乎使用者連結:https://www.zhihu.com/question/27704562/answer/37760739來源:知乎著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。不使用編譯器擴充套件,不用C++11,不加鎖,也不使用原子操作的話

設計模式C++實現 1.模式

單例模式即實現單例類,即系統中一個類只有一個例項,而且該例項易於外界訪問。這樣方便對例項個數進行控制並節約系統資源。 而單例常用與一些非區域性靜態物件,對於這些物件,程式難以控制,對於這些存在與全域性,且一般持久存在的物件,有時需要按照一定約束或順序來進行初始化,而初始化這

Objective-C 中singleton(模式)的實現

OC中的單例很有意思,因為沒辦法像JAVA或C++中把建構函式設為private的來防止其它人直接 new 一個新物件,所以像如下單例的實現方式,只能祈禱大家必須按你要求的方式建立物件,有人不小心直接 [[ xx alloc] init] 建立一個物件,是很難發現的。 s

C++中的模式(懶漢模式、餓漢模式及執行緒安全問題)

1 教科書裡的單例模式   我們都很清楚一個簡單的單例模式該怎樣去實現:建構函式宣告為private或protect防止被外部函式例項化,內部儲存一個private static的類指標儲存唯一的例項,例項的動作由一個public的類方法代勞,該方法也返回單例類唯一的例

C++如何實現模式

C++有時會用到單例模式,比如和資料庫連線的類,我們只需要一個物件,那麼這時候我們就要限制類物件產生的數量,允許一個類產生一個物件,如何讓一個類產生一個物件呢,也就是實現單例模式? 方法一:將建構函式

C++實現懶漢式模式

單例模式無論在生活中還是在工程中都有很廣泛的應用,在C++專案中,很多時候我們只希望整個工程中某個類僅有一個實體物件,設計這種類的時候就需要使用單例模式來設計。下面是實現的一個懶漢式單例模式的程式碼: #include <iostream> #in

C++實現模式4——C++11實現

std::atomic<Singleton*> Singleton::m_instance; std::mutex Singleton::m_mutex; Singleton* Singleton::getInstance() { Singleton* tmp = m_instance

C++11下的模式

動機:在軟體系統中,經常有這樣一些特殊的類,必須保證它們在系統中只存在一個例項,才能確保它們的邏輯正確性、以及良好的效率。  繞過常規的構造器,提供一種機制來保證一個類只有一個例項。 定義:保證一個類僅有一個例項,並提供一個該例項的全域性訪問點。 1、C++11中可以保證sta