大話設計模式C++版本-06-原型模式

概念

原型模式:用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。
原理:利用一個Clone函數來封裝了自身的拷貝構造函數,調用Clone函數時就會觸發拷貝構造。

使用場景

利用已有的一個原型對象,快速地生成和原型對象一樣的實例

一般步驟

  1. 設計一個接口類,這步感覺可有可無;
    class ICloneable
    {
    public:
    	virtual ICloneable *Clone()=0;
    };
    
  2. 寫一個類用來繼承前面的接口類,並實現克隆方法,如果需要深拷貝的話,需要自己實現拷貝構造函數;
    關於拷貝構造函數,或者淺拷貝、深拷貝有不清楚的可以看這《C++入門知識-拷貝構造函數-淺拷貝、深拷貝》
    class Resume : public ICloneable // 簡歷類
    {
    private:
       string name;	// 名字
       string sex;		// 性別
       string age;		// 年齡
       WorkExperience *work; // 工作
    public:
       #if DEEP_COPY
       Resume(const Resume &resume) //拷貝構造函數,實現深拷貝
       {
       	this->name = resume.name;
       	this->sex = resume.sex;
       	this->age = resume.age;
       	cout<<resume.work->workDate<<" "<<resume.work->workCompany<<endl;
       	this->work = new WorkExperience();
       	this->work->workDate = resume.work->workDate;
       	this->work->workCompany = resume.work->workCompany;
       }
       #endif
       ICloneable *Clone()
       {
       	return new Resume(*this); // 關鍵步驟:調用拷貝構造函數,將當前對象的非靜態字段複製到新對象
       }
    };
    

具體實例完整代碼

//06Prototype.cpp
#include <iostream>
#include <string>

using namespace std;
#define DEEP_COPY 1
class ICloneable
{
public:
	virtual ICloneable *Clone()=0;
};

class WorkExperience
{
public:
	string workDate;
	string workCompany;
};

class Resume : public ICloneable // 簡歷類
{
private:
	string name;	// 名字
	string sex;		// 性別
	string age;		// 年齡
	WorkExperience *work; // 工作
public:
	#if DEEP_COPY
	Resume(const Resume &resume) //拷貝構造函數,實現深拷貝
	{
		this->name = resume.name;
		this->sex = resume.sex;
		this->age = resume.age;
		cout << resume.work->workDate << " " << resume.work->workCompany << endl;
		this->work = new WorkExperience();
		this->work->workDate = resume.work->workDate;
		this->work->workCompany = resume.work->workCompany;
	}
	#endif
	Resume(string name)
	{
		this->name = name;
		this->work = new WorkExperience();
	}
	
	void SetPersonalInfo(string age, string sex)
	{
		this->sex = sex;
		this->age = age;
	}
	
	void SetWorkExperience(string workDate, string workCompany)
	{
		this->work->workDate = workDate;
		this->work->workCompany = workCompany;
	}
	
	void Display()
	{
		cout << name << " " << sex << " " << age << endl;
		cout << work->workDate << " " << work->workCompany << endl;
		cout << &work->workDate << " " << &work->workCompany << endl;
	}
	
	ICloneable *Clone()
	{
		// 關鍵步驟:調用拷貝構造函數,將當前對象的非靜態字段複製到新對象
		return new Resume(*this);
	}
};

int main()
{
	Resume *a = new Resume("大鳥");
	a->SetPersonalInfo("男","29");
	a->SetWorkExperience("1998-2000","XX公司");
	a->Display();
	
	Resume *b = (Resume *)a->Clone();
	b->Display();
	
	// 其實按照下面這種調用也會觸發拷貝構造函數,效果和這個模式一樣
	Resume *c = a;
	c->Display();
	return 0;
}

參考資料

程傑老師的《大話設計模式》
C++設計模式——原型模式(Prototype Pattern)

如果對你有幫助的話,記得點贊收藏,如果有什麼遺漏的或者有什麼體會,請在評論告訴我,好東西記得分享 ^ _ ^

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章