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

## 一般步驟

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)