前言
那么這里博主先安利一些干貨滿(mǎn)滿(mǎn)的專(zhuān)欄了!
首先是博主的高質(zhì)量博客的匯總,這個(gè)專(zhuān)欄里面的博客,都是博主最最用心寫(xiě)的一部分,干貨滿(mǎn)滿(mǎn),希望對(duì)大家有幫助。
高質(zhì)量干貨博客匯總https://blog.csdn.net/yu_cblog/category_12379430.html?spm=1001.2014.3001.5482
什么是單例模式
一個(gè)類(lèi)只能創(chuàng)建一個(gè)對(duì)象,即單例模式,該模式可以保證系統(tǒng)中該類(lèi)只有一個(gè)實(shí)例,并提供一個(gè)訪(fǎng)問(wèn)它的全 局訪(fǎng)問(wèn)點(diǎn),該實(shí)例被所有程序模塊共享。比如在某個(gè)服務(wù)器程序中,該服務(wù)器的配置信息存放在一個(gè)文件 中,這些配置數(shù)據(jù)由一個(gè)單例對(duì)象統(tǒng)一讀取,然后服務(wù)進(jìn)程中的其他對(duì)象再通過(guò)這個(gè)單例對(duì)象獲取這些配置 信息,這種方式簡(jiǎn)化了在復(fù)雜環(huán)境下的配置管理。
單例模式有兩種實(shí)現(xiàn)方式:
- 餓漢模式
- 懶漢模式
餓漢模式
就是說(shuō)不管你將來(lái)用不用,程序啟動(dòng)時(shí)就創(chuàng)建一個(gè)唯一的實(shí)例對(duì)象。
優(yōu)點(diǎn):
- 簡(jiǎn)單、沒(méi)有線(xiàn)程安全問(wèn)題
缺點(diǎn):
- 當(dāng)一個(gè)程序中有多個(gè)單例,并且有先后初始化順序的要求的時(shí)候,餓漢無(wú)法控制。
- 餓漢單例類(lèi)創(chuàng)建得多的時(shí)候,初始化任務(wù)多的時(shí)候,會(huì)影響程序的啟動(dòng)速度。
//設(shè)計(jì)只能創(chuàng)建一個(gè)對(duì)象的類(lèi)(單例模式)
//有兩種設(shè)計(jì)方案
//餓漢模式 -- 一開(kāi)始(main())之前就創(chuàng)建出對(duì)象了
#if 1
class MemoryPool //假設(shè)要求設(shè)計(jì)一個(gè)內(nèi)存池 -- 要求是單例的 ,當(dāng)然只是名字而已,我們不是真的實(shí)現(xiàn)內(nèi)存池
{
public:
static MemoryPool* GetInstance()
{
return _pinst;
}
void* Alloc(size_t n)
{
void* ptr = nullptr;
//...
//里面啥東西我們不管
return ptr;
}
void Dealloc(void* ptr)
{
//...
}
protected:
char* _ptr = nullptr;
protected:
//構(gòu)造函數(shù)私有
MemoryPool() {}
//兩種寫(xiě)法,這里只寫(xiě)了一種,寫(xiě)成指針也可以,不寫(xiě)成指針也可以
static MemoryPool* _pinst;//聲明
};
MemoryPool* MemoryPool::_pinst = new MemoryPool;
#define MemoryPoolObject MemoryPool::GetInstance()
int main()
{
//一般是這樣調(diào)用的,直接調(diào)就行
void* ptr1 = MemoryPool::GetInstance()->Alloc(10);
MemoryPool::GetInstance()->Dealloc(ptr1);
//單例模式一般就是通過(guò)這個(gè) MemoryPool::GetInstance() 去找到這個(gè)已經(jīng)創(chuàng)建好的對(duì)象,去調(diào)它里面的東西
void* ptr2 = MemoryPoolObject->Alloc(29);
MemoryPoolObject->Dealloc(ptr2);
return 0;
}
#endif
懶漢模式
對(duì)象第一次使用的時(shí)候再創(chuàng)建。
優(yōu)點(diǎn):文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-604987.html
- 可以控制順序
- 不影響啟動(dòng)速度
缺點(diǎn):文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-604987.html
- 相對(duì)復(fù)雜
- 線(xiàn)程安全問(wèn)題要處理好
//懶漢模式
//對(duì)象第一次使用的時(shí)候再創(chuàng)建
class MemoryPool //假設(shè)要求設(shè)計(jì)一個(gè)內(nèi)存池 -- 要求是單例的 ,當(dāng)然只是名字而已,我們不是真的實(shí)現(xiàn)內(nèi)存池
{
public:
static MemoryPool* GetInstance()
{
//如果發(fā)現(xiàn)指針是nullptr的時(shí)候,說(shuō)明我們是第一次使用這個(gè)類(lèi)
if (_pinst == nullptr)
{
//第一次創(chuàng)建
cout << "第一次創(chuàng)建對(duì)象" << endl;
_pinst = new MemoryPool;
}
return _pinst;
}
void* Alloc(size_t n)
{
void* ptr = nullptr;
//...
//里面啥東西我們不管
return ptr;
}
void Dealloc(void* ptr)
{
//...
}
class CGarbo
{
public:
~CGarbo()
{
if (_pinst)delete _pinst;
}
};
protected:
char* _ptr = nullptr;
protected:
//構(gòu)造函數(shù)私有
MemoryPool() {}
//兩種寫(xiě)法,這里只寫(xiě)了一種,寫(xiě)成指針也可以,不寫(xiě)成指針也可以
static MemoryPool* _pinst;//聲明
};
MemoryPool* MemoryPool::_pinst = nullptr;
//回收對(duì)象
//在main結(jié)束之后,它會(huì)調(diào)用析構(gòu)函數(shù),就會(huì)釋放單例對(duì)象
static MemoryPool::CGarbo gc;
#define MemoryPoolObject MemoryPool::GetInstance()
int main()
{
//一般是這樣調(diào)用的,直接調(diào)就行
cout << " -------- 第一次使用 -------- " << endl;
void* ptr1 = MemoryPool::GetInstance()->Alloc(10);
MemoryPool::GetInstance()->Dealloc(ptr1);
//單例模式一般就是通過(guò)這個(gè) MemoryPool::GetInstance() 去找到這個(gè)已經(jīng)創(chuàng)建好的對(duì)象,去調(diào)它里面的東西
cout << " -------- 第二次使用 -------- " << endl;
void* ptr2 = MemoryPoolObject->Alloc(29);
MemoryPoolObject->Dealloc(ptr2);
return 0;
}
單例模式的釋放問(wèn)題
- 一般情況下,單例對(duì)象不需要釋放 -- 一般來(lái)說(shuō)整個(gè)程序運(yùn)行期間都會(huì)用它。單例對(duì)象再進(jìn)程正常結(jié)束之后,也會(huì)資源釋放。
- 有些特殊場(chǎng)景需要釋放,比如單例對(duì)象析構(gòu)時(shí)候,需要進(jìn)行一些持久化操作(往文件、數(shù)據(jù)庫(kù)里面去寫(xiě)),大思路:定義一個(gè)內(nèi)部的垃圾回收類(lèi)
到了這里,關(guān)于單例模式類(lèi)設(shè)計(jì)|什么是餓漢模式和懶漢模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!