生活随笔
收集整理的這篇文章主要介紹了
设计模式C++实现(8)——代理模式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ? 軟件領域中的設計模式為開發人員提供了一種使用專家設計經驗的有效途徑。設計模式中運用了面向對象編程語言的重要特性:封裝、繼承、多態,真正領悟設計模式的精髓是可能一個漫長的過程,需要大量實踐經驗的積累。最近看設計模式的書,對于每個模式,用C++寫了個小例子,加深一下理解。主要參考《大話設計模式》和《設計模式:可復用面向對象軟件的基礎》(DP)兩本書。本文介紹代理模式的實現。
??????? [DP]上的定義:為其他對象提供一種代理以控制對這個對象的訪問。有四種常用的情況:(1)遠程代理,(2)虛代理,(3)保護代理,(4)智能引用。本文主要介紹虛代理和智能引用兩種情況。
???????考慮一個可以在文檔中嵌入圖形對象的文檔編輯器。有些圖形對象的創建開銷很大。但是打開文檔必須很迅速,因此我們在打開文檔時應避免一次性創建所有開銷很大的對象。這里就可以運用代理模式,在打開文檔時,并不打開圖形對象,而是打開圖形對象的代理以替代真實的圖形。待到真正需要打開圖形時,仍由代理負責打開。這是[DP]一書上的給的例子。下面給出代理模式的UML圖。
?????? 簡單實現如下:
[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();?? ????}?? };??
?????????客戶調用:
[cpp]?view plaincopy print?
int?main()?? {?? ????Image?*image?=?new?BigImageProxy("proxy.jpg");??? ????image->Show();??? ????delete?image;?? ????return?0;?? }??
???????? 在這個例子屬于虛代理的情況,下面給兩個智能引用的例子。一個是C++中的auto_ptr,另一個是smart_ptr。自己實現了一下。先給出auto_ptr的代碼實現:
[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;???? };????
????????閱讀上面的代碼,我們可以發現 auto_ptr 類就是一個代理,客戶只需操作auto_prt的對象,而不需要與被代理的指針pointee打交道。auto_ptr?的好處在于為動態分配的對象提供異常安全。因為它用一個對象存儲需要被自動釋放的資源,然后依靠對象的析構函數來釋放資源。這樣客戶就不需要關注資源的釋放,由auto_ptr 對象自動完成。實現中的一個關鍵就是重載了解引用操作符和箭頭操作符,從而使得auto_ptr的使用與真實指針類似。
???????我們知道C++中沒有垃圾回收機制,可以通過智能指針來彌補,下面給出智能指針的一種實現,采用了引用計數的策略。
[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;?? ????????}?? ????}?? };??
? ? ? ?
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
總結
以上是生活随笔為你收集整理的设计模式C++实现(8)——代理模式的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。