概念
原型模式:用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。
原理:利用一個Clone函數來封裝了自身的拷貝構造函數,調用Clone函數時就會觸發拷貝構造。
使用場景
利用已有的一個原型對象,快速地生成和原型對象一樣的實例
一般步驟
- 設計一個接口類,這步感覺可有可無;
class ICloneable { public: virtual ICloneable *Clone()=0; };
- 寫一個類用來繼承前面的接口類,並實現克隆方法,如果需要深拷貝的話,需要自己實現拷貝構造函數;
關於拷貝構造函數,或者淺拷貝、深拷貝有不清楚的可以看這《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)
如果對你有幫助的話,記得點贊、收藏,如果有什麼遺漏的或者有什麼體會,請在評論告訴我,好東西記得分享 ^ _ ^