生活随笔
收集整理的這篇文章主要介紹了
设计模式C++实现(8)——代理模式
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
? ? 軟件領(lǐng)域中的設(shè)計(jì)模式為開(kāi)發(fā)人員提供了一種使用專家設(shè)計(jì)經(jīng)驗(yàn)的有效途徑。設(shè)計(jì)模式中運(yùn)用了面向?qū)ο缶幊陶Z(yǔ)言的重要特性:封裝、繼承、多態(tài),真正領(lǐng)悟設(shè)計(jì)模式的精髓是可能一個(gè)漫長(zhǎng)的過(guò)程,需要大量實(shí)踐經(jīng)驗(yàn)的積累。最近看設(shè)計(jì)模式的書(shū),對(duì)于每個(gè)模式,用C++寫(xiě)了個(gè)小例子,加深一下理解。主要參考《大話設(shè)計(jì)模式》和《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》(DP)兩本書(shū)。本文介紹代理模式的實(shí)現(xiàn)。
??????? [DP]上的定義:為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。有四種常用的情況:(1)遠(yuǎn)程代理,(2)虛代理,(3)保護(hù)代理,(4)智能引用。本文主要介紹虛代理和智能引用兩種情況。
???????考慮一個(gè)可以在文檔中嵌入圖形對(duì)象的文檔編輯器。有些圖形對(duì)象的創(chuàng)建開(kāi)銷很大。但是打開(kāi)文檔必須很迅速,因此我們?cè)诖蜷_(kāi)文檔時(shí)應(yīng)避免一次性創(chuàng)建所有開(kāi)銷很大的對(duì)象。這里就可以運(yùn)用代理模式,在打開(kāi)文檔時(shí),并不打開(kāi)圖形對(duì)象,而是打開(kāi)圖形對(duì)象的代理以替代真實(shí)的圖形。待到真正需要打開(kāi)圖形時(shí),仍由代理負(fù)責(zé)打開(kāi)。這是[DP]一書(shū)上的給的例子。下面給出代理模式的UML圖。
?????? 簡(jiǎn)單實(shí)現(xiàn)如下:
[cpp]?view plaincopy print?
class?Image?? {?? public:?? ????Image(string?name):?m_imageName(name)?{}?? ????virtual?~Image()?{}?? ????virtual?void?Show()?{}?? protected:?? ????string?m_imageName;?? };?? class?BigImage:?public?Image?? {?? public:?? ????BigImage(string?name):Image(name)?{}?? ????~BigImage()?{}?? ????void?Show()?{?cout<<"Show?big?image?:?"<<m_imageName<<endl;?}?? };?? class?BigImageProxy:?public?Image?? {?? private:?? ????BigImage?*m_bigImage;?? public:?? ????BigImageProxy(string?name):Image(name),m_bigImage(0)?{}?? ????~BigImageProxy()?{?delete?m_bigImage;?}?? ????void?Show()??? ????{?? ????????if(m_bigImage?==?NULL)?? ????????????m_bigImage?=?new?BigImage(m_imageName);?? ????????m_bigImage->Show();?? ????}?? };??
?????????客戶調(diào)用:
[cpp]?view plaincopy print?
int?main()?? {?? ????Image?*image?=?new?BigImageProxy("proxy.jpg");??? ????image->Show();??? ????delete?image;?? ????return?0;?? }??
???????? 在這個(gè)例子屬于虛代理的情況,下面給兩個(gè)智能引用的例子。一個(gè)是C++中的auto_ptr,另一個(gè)是smart_ptr。自己實(shí)現(xiàn)了一下。先給出auto_ptr的代碼實(shí)現(xiàn):
[cpp]?view plaincopy print?
template<class?T>???? class?auto_ptr?{???? public:???? ????explicit?auto_ptr(T?*p?=?0):?pointee(p)?{}???? ????auto_ptr(auto_ptr<T>&?rhs):?pointee(rhs.release())?{}???? ????~auto_ptr()?{?delete?pointee;?}???? ????auto_ptr<T>&?operator=(auto_ptr<T>&?rhs)???? ????{???? ????????if?(this?!=?&rhs)?reset(rhs.release());???? ????????return?*this;???? ????}???? ????T&?operator*()?const?{?return?*pointee;?}???? ????T*?operator->()?const?{?return?pointee;?}???? ????T*?get()?const?{?return?pointee;?}???? ????T*?release()???? ????{???? ????????T?*oldPointee?=?pointee;???? ????????pointee?=?0;???? ????????return?oldPointee;???? ????}???? ????void?reset(T?*p?=?0)???? ????{???? ????????if?(pointee?!=?p)?{???? ???????????????delete?pointee;???? ???????????????pointee?=?p;???? ????????????}???? ????????}???? private:???? ????T?*pointee;???? };????
????????閱讀上面的代碼,我們可以發(fā)現(xiàn) auto_ptr 類就是一個(gè)代理,客戶只需操作auto_prt的對(duì)象,而不需要與被代理的指針pointee打交道。auto_ptr?的好處在于為動(dòng)態(tài)分配的對(duì)象提供異常安全。因?yàn)樗靡粋€(gè)對(duì)象存儲(chǔ)需要被自動(dòng)釋放的資源,然后依靠對(duì)象的析構(gòu)函數(shù)來(lái)釋放資源。這樣客戶就不需要關(guān)注資源的釋放,由auto_ptr 對(duì)象自動(dòng)完成。實(shí)現(xiàn)中的一個(gè)關(guān)鍵就是重載了解引用操作符和箭頭操作符,從而使得auto_ptr的使用與真實(shí)指針類似。
???????我們知道C++中沒(méi)有垃圾回收機(jī)制,可以通過(guò)智能指針來(lái)彌補(bǔ),下面給出智能指針的一種實(shí)現(xiàn),采用了引用計(jì)數(shù)的策略。
[cpp]?view plaincopy print?
template?<typename?T>?? class?smart_ptr?? {?? public:?? ????smart_ptr(T?*p?=?0):?pointee(p),?count(new?size_t(1))?{?}???? ????smart_ptr(const?smart_ptr?&rhs):?pointee(rhs.pointee),?count(rhs.count)?{?++*count;?}??? ????~smart_ptr()?{?decr_count();?}???????????????? ????smart_ptr&?operator=?(const?smart_ptr&?rhs)??? ????{?? ?????????? ????????++*count;?? ????????decr_count();?? ????????pointee?=?rhs.pointee;?? ????????count?=?rhs.count;?? ????????return?*this;?? ????}???? ?????? ????T?*operator->()?{?return?pointee;?}?? ????const?T?*operator->()?const?{?return?pointee;?}?? ????T?&operator*()?{?return?*pointee;?}?? ????const?T?&operator*()?const?{?return?*pointee;?}?? ????size_t?get_refcount()?{?return?*count;?}??? private:??? ????T?*pointee;????????? ????size_t?*count;?????? ????void?decr_count()??? ????{?? ????????if(--*count?==?0)??? ????????{?? ????????????delete?pointee;?? ????????????delete?count;?? ????????}?? ????}?? };??
? ? ? ?
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀
總結(jié)
以上是生活随笔為你收集整理的设计模式C++实现(8)——代理模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。