文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-652090.html
一.單例模式
- 一個(gè)類(lèi)只能創(chuàng)建一個(gè)對(duì)象,這樣的類(lèi)的設(shè)計(jì)模式就稱(chēng)為單例模式,該模式保證系統(tǒng)中該類(lèi)只能有一個(gè)實(shí)例(并且父子進(jìn)程共享),一個(gè)很典型的單例類(lèi)就是C++STL的內(nèi)存池
-
C++單例模式的基本設(shè)計(jì)思路:
- 私有化構(gòu)造函數(shù),刪除默認(rèn)的拷貝構(gòu)造函數(shù)和賦值運(yùn)算符重載防止對(duì)象被直接創(chuàng)建和拷貝
- 單例對(duì)象的內(nèi)存資源可以交給操作系統(tǒng)來(lái)釋放,也可以自定義析構(gòu)函數(shù)來(lái)完成特殊操作
二.單例模式的兩種實(shí)現(xiàn)方式
餓漢模式
- 餓漢單例類(lèi)在程序進(jìn)入主函數(shù)之前就創(chuàng)建出唯一的實(shí)例
//餓漢單例模式
class HungerSingleton
{
public:
//定義一個(gè)可以訪問(wèn)單例對(duì)象的靜態(tài)接口
static HungerSingleton* Getinstance()
{
return &singleObj;
}
private:
//構(gòu)造函數(shù)私有化,防止對(duì)象被直接創(chuàng)建
HungerSingleton() { cout << "單例對(duì)象創(chuàng)建" << endl; }
//刪除拷貝接口,防止對(duì)象被拷貝
HungerSingleton(const HungerSingleton& single) = delete;
HungerSingleton& operator=(const HungerSingleton& single) = delete;
private:
//定義靜態(tài)區(qū)的HungerSingleton成員
static HungerSingleton singleObj;
//也可以定義成指針,初始化時(shí)在堆上創(chuàng)建
//static HungerSingleton* singleObj;
};
//初始化類(lèi)的靜態(tài)成員
HungerSingleton HungerSingleton::singleObj;
//初始化時(shí)在堆上創(chuàng)建
//HungerSingleton * HungerSingleton::singleObj = new HungerSingleton;
HungerSingleton
的靜態(tài)成員變量是自身類(lèi)型的對(duì)象(或指針),類(lèi)的靜態(tài)成員變量在進(jìn)入主函數(shù)之前就完成初始化,由于構(gòu)造函數(shù)被私有化,因此在程序運(yùn)行過(guò)程中無(wú)法再創(chuàng)建該類(lèi)的對(duì)象-
餓漢單例模式的優(yōu)勢(shì):
- 由于子進(jìn)程只能在主函數(shù)中被創(chuàng)建,因此餓漢單例類(lèi)不存在線程安全問(wèn)題,無(wú)需與其他線程的類(lèi)競(jìng)爭(zhēng)系統(tǒng)資源,在多線程高并發(fā)環(huán)境下能夠較為高效地執(zhí)行任務(wù)
-
餓漢單例模式的劣勢(shì):
- 如果一個(gè)程序中有多種餓漢單例類(lèi),我們無(wú)法控制它們的初始化順序
- 餓漢單例類(lèi)會(huì)拖慢程序的啟動(dòng)速度,而且即便用不到該類(lèi)也會(huì)創(chuàng)建一個(gè)實(shí)例,可能造成內(nèi)存浪費(fèi)
懶漢模式
- 懶漢單例類(lèi)在程序進(jìn)入主函數(shù)之后由后續(xù)代碼決定是否創(chuàng)建實(shí)例
//懶漢單例模式
class LazySingleton
{
public:
//定義一個(gè)可以訪問(wèn)單例對(duì)象的靜態(tài)接口
static LazySingleton* Getinstance()
{
//若singleObj為空指針則創(chuàng)建單例對(duì)象
if (singleObj == nullptr)
{
singleObj = new LazySingleton;
}
return singleObj;
}
private:
//構(gòu)造函數(shù)私有化,防止對(duì)象被創(chuàng)建
LazySingleton() { cout << "單例對(duì)象創(chuàng)建" << endl; }
//刪除拷貝接口,防止對(duì)象被拷貝
LazySingleton(const LazySingleton& single) = delete;
LazySingleton& operator=(const LazySingleton& single) = delete;
private:
//定義成靜態(tài)成員指針,初始化時(shí)在堆上創(chuàng)建
static LazySingleton* singleObj;
};
//初始化時(shí)設(shè)置成空指針
LazySingleton * LazySingleton::singleObj = nullptr;
LazySingleton
類(lèi)在第一次調(diào)用Getinstance()
成員接口時(shí)才會(huì)創(chuàng)建實(shí)例-
懶漢單例模式的優(yōu)勢(shì):
- 可以控制多種懶漢單例類(lèi)對(duì)象的初始化順序,并且需要用到的時(shí)候才創(chuàng)建,避免了內(nèi)存浪費(fèi)
-
懶漢單例模式的劣勢(shì):
-
在多線程環(huán)境中存在線程安全問(wèn)題,需要加鎖
-
在多線程環(huán)境中存在線程安全問(wèn)題,需要加鎖
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-652090.html
到了這里,關(guān)于設(shè)計(jì)模式 : 單例模式筆記的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!