c 單例的實現

2021-07-09 06:50:37 字數 2713 閱讀 6787

單例的實現有很多的坑,並不是簡單的乙個static的成員獲取就算是單例了,下面詳細敘述下它的坑。

-.  懶漢模式

class singleton

};

懶漢模式在一般使用下都不會有問題,但是,這個實現是執行緒不安全的。區域性靜態變數static singleton minstance ,編譯器會在編譯時期對其做處理,其結果如下:

static bool s_constructed = false;

static uninitialized singleton minstance;

if (!s_constructed)

二. 餓漢模式

我們知道 , 全域性成員,類靜態成員,都是在main函式執行前進行初始化的,而區域性靜態成員是在執行到它的時候才進行初始化,所以餓漢模式就是在程式還沒有執行的時候,就對單例進行初始化。

class singleton

};

singleton singleton::minstance;
這樣,就不會存在編譯器對於懶漢模式所做的處理了,在main函式執行前,singleton物件就已經夠造了出來,這樣就是乙個執行緒安全的單例模式了。

以為這就是單例模式最終的形態了嗎? too young too ******!!!!!

template struct singleton

inline void do_nothing()const {}

};static object_creator create_object;

public:

typedef t object_type;

static object_type& instance()

};template typename singleton::object_creator singleton::create_object;

發現有這麼乙個實現,將單例物件還是做程區域性靜態變數,但是通過另乙個內部類object_creator代替其在全域性區宣告初始化,這是什麼原因呢?

//.h

class qmmanager

;public:

static qmmanager *instance()

}; class qmsqlite

;public:

static qmsqlite *instance()

void do_something();};

qmmanager qmmanager::instance_;

qmsqlite qmsqlite::instance_;

//.cpp

qmmanager::qmmanager()

qmsqlite::qmsqlite()

void qmsqlite::do_something()

就是在構造類靜態成員的時候,它的建構函式有可能去呼叫另乙個單例模式的靜態成員,以便呼叫其方法。可以發現,這是存在問題的,在執行main函式之前,兩個靜態成員qmanager和qmssqlite的構造是有先後順序的,qmanager先進行的初始化,這時候,當呼叫qmanager的建構函式的時候,去主動獲取qmsqlite的單例,並呼叫其成員,但是,這時候qmsqlite的單例物件instance_還沒有初始化,就是說,現在呼叫的是乙個為初始化的變數,這當然存在問題了。 解決的辦法就是,將這兩個變數的初始化工作放在區域性變數,讓程式執行到的時候去初始化。但是這樣就又會出現懶漢模式中的執行緒不安全的問題,所以,討巧的做法就是把他們封裝進另乙個靜態成員的構造中。

最終的單例模式:

class singleton

};static create_object m_createobj;

public:

~singleton();

static singleton& getinstance();

void eat()

};

singleton::create_object singleton::m_createobj; 

singleton::singleton()

singleton::~singleton()

singleton& singleton::getinstance()

小小的單例模式,有這麼多的坑

貼一段模仿boost的實現:

#include "stdafx.h"

#include using namespace std;

class signletonst

~signletonst(){}

struct create_signletonst

};static create_signletonst m_creator;

public:

static signletonst* getinstance()

else

} };

signletonst::create_signletonst signletonst::m_creator;

int _tmain(int argc, _tchar* argv)

c 單例實現

1.物件指標實現 class singleton unlock return m pinstance int getdata const private singleton m test 888 class cgarbo cgarbo static cgarbo m garbo static sin...

c 實現單例

單例巨集 單件定義巨集 在標頭檔案中申明 declare singleobj csampleclass 在cpp檔案中定義靜態變數 implement singleobj csampleclass 注意單件的getinstance為非執行緒安全,最好是在主線程初始化的時候呼叫一次 define de...

c 實現單例

單例巨集 單件定義巨集 在標頭檔案中申明 declare singleobj csampleclass 在cpp檔案中定義靜態變數 implement singleobj csampleclass 注意單件的getinstance為非執行緒安全,最好是在主線程初始化的時候呼叫一次 define de...