(轉)設計模式(6):原型模式
阿新 • • 發佈:2019-02-17
定義:用原型例項指定建立物件的種類,並通過拷貝這些原型建立新的物件。
型別:建立類模式
類圖:
原型模式主要用於物件的拷貝,拷貝又分淺拷貝和深拷貝兩種。
- 淺拷貝:就是給物件中的每個成員變數進行復制,就是把A1類中的變數直接賦給A2類中變數,屬於值傳遞,但是涉及到有new之類記憶體分配的地方,他們卻是共享記憶體的。
- 深拷貝:就是不僅使用值傳遞,而是要每個變數都有自己一份獨立的記憶體空間,互不干擾。
為什麼要用到深拷貝?
如果實行位拷貝,也就是把物件裡的值完全複製給另一個物件,如A=B。這時,如果B中有一個成員變數指標已經申請了記憶體,那A中的那個成員變數也指向同一塊記憶體。這就出現了問題:當B把記憶體釋放了(如:析構),這時A內的指標就是野指標了,出現執行錯誤。
程式碼實現:
#include <cstdio> //介面 class CPrototype { public: CPrototype(){} virtual ~CPrototype(){} virtual CPrototype* Clone() = 0; }; //實現 class CConcretePrototype : public CPrototype { public: CConcretePrototype():m_counter(0){} virtual ~CConcretePrototype(){} //拷貝建構函式 CConcretePrototype(const CConcretePrototype& rhs) { m_counter = rhs.m_counter; } //複製自身 virtual CPrototype* Clone() { //呼叫拷貝建構函式 return new CConcretePrototype(*this); } private: int m_counter; }; int main(int argc, char **argv) { //生成對像 CPrototype* conProA = new CConcretePrototype(); //複製自身 CPrototype* conProB = conProA->Clone(); delete conProA; conProA=NULL; delete conProB; conProB=NULL; return 0; }
原型模式的優點及適用場景
優點:
- 使用拷貝模式比直接new一個物件的開銷要小的多。
- 使用原型模式的另一個好處是簡化物件的建立,使得建立物件就像我們在編輯文件時的複製貼上一樣簡單。
- 可以在程式執行時(物件屬性發生了變化),得到一份內容相同的例項,但之間還不會相互干擾。
- 基本就是你需要從A的例項得到一份與A內容相同,但是又互不干擾的例項的話,就需要使用原型模式。
適用場景:
因為以上優點,所以在需要重複地建立相似物件時可以考慮使用原型模式。比如需要在一個迴圈體內建立物件,假如物件建立過程比較複雜或者迴圈次數很多的話,使用原型模式不但可以簡化建立過程,而且可以使系統的整體效能提高很多。
原型模式的注意事項
深拷貝與淺拷貝:一般的拷貝方法只會拷貝物件中的基本的資料型別,對於陣列、容器物件、引用物件等都不會拷貝,這就是淺拷貝。如果要實現深拷貝,必須將原型模式中的陣列、容器物件、引用物件等另行拷貝。