單例的實現有很多的坑,並不是簡單的乙個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...