其实我觉得原型模式就是实现对原型的复制,这是这个复制是创建出新的对象
原型模式:**用原型实例来制定创建对象的种类,并且通过拷贝这些原型来创建新的对象。**注意这里是新的对象,而我们一般的拷贝是浅拷贝,当我们把原版(第一份delete时),后面的浅拷贝的对象全部失效。所以这里使用原型模式
因为已经实际的拷贝出来几个副本,即使原版内存被释放也没有影响。
参考:设计模式C++实现(5)——原型模式、模板方法模式
设计模式之原型模式(c++)
//没有使用原型模式
Resume *pp = new Resume("大鸟");
pp->SetSex_Age("男", 18);
pp->Set_Workexper("boe", "2018.10-2020.10");
Resume *b = pp;
b->SetSex_Age("女",15);
b->Set_Workexper("bbb", "2002.10-2005.10");
Resume *c = pp;
//delete pp; //如果这里我们释放pp的内存,新成员b和c都是从pp拷贝过来,就无法实现,因为内存已经被释放
pp->Display(); //在这里我们连同pp内容都修改为女,15,就没有原版(我们的意图只是简单的改掉后续b和c)
b->Display();
c->Display();
而原型模式的实质就是实现对于原型的拷贝。
就拿《大话设计结构》中简历为例:现在我们有一份简历(原版),我们要对它拷贝很多份去投给各个公司(谷歌,腾讯,阿里,百度等等)。
对于不同的公司,我们投的岗位可能不一样,工作经历也可能写的不一样,这样的话我们需要对“原版”简历进行修改以适应各个公司,但是我们又不希望原版被改变(毕竟原版是适合大多数公司的)。
这里我们就需要去实现原型模式(clone),也就是实现下面的UML图。
下面开始实现,以简历 为例
Resume.h
#include <iostream>
#include <string>
using namespace std;
class Resume
{
private:
string m_name;
string m_sex;
string m_workexper;
int m_age;
string m_worktime;
public:
Resume(string name) { m_name = name; }
Resume(){}
void SetSex_Age(string sex, int age) { this->m_sex = sex; this->m_age = age; }
void Set_Workexper(string exper, string worktime) { this->m_workexper = exper; this->m_worktime = worktime; }
void Display() {
cout << "姓名:" << m_name << endl
<< "性别:" << m_sex << endl
<< "年龄:" << m_age << endl;
cout << "工作经历:" << endl << m_worktime << "," << m_workexper << endl;
}
virtual Resume *clone() = 0; //定义一个纯虚函数,纯虚函数就是虚基类,这里就是一个接口,接口不能实例化一个对象,它的作用就是被子类继承,
//但是它可以定义指针或者引用。
~Resume();
};
class ResumeA :public Resume {
public:
ResumeA(string s) :Resume(s) {}
ResumeA() {}
~ResumeA() {}
***Resume *clone() {
ResumeA *p = new ResumeA(); //这里就是实现了上图中的return copy of self
*p = *this;
return p;
//return new ResumeA(*this); //或者用这一句话替代上面三句
}***
};
class ResumeB :public Resume {
public:
ResumeB(string s):Resume(s) {}
ResumeB() {}
~ResumeB() {}
***Resume *clone() {
ResumeB *p = new ResumeB();//这里就是实现了上图中的return copy of self
*p = *this;
return p;
// return new ResumeB(*this); //或者用这一句话替代上面三句
}***
};
// DaHuaSheJiJieGou.cpp :主函数
//
#include "stdafx.h"
#include "Calculate.h"
#include "Factory.h"
#include "Resume.h"
#include <iostream>
#include <memory>
using namespace std;
int main()
{
Resume *pp = new ResumeA("pp");
pp->SetSex_Age("男", 16);
pp->Set_Workexper("action", "1998-2010");
Resume *qq = (ResumeB *)pp->clone();
qq->SetSex_Age("girl", 16);
qq->Set_Workexper("hah", "2001-2019");
Resume *ss = qq->clone();
pp->Display();
qq->Display();
delete pp; //在这里即使我们把pp和qq释放了也没什么关系,因为我们已经拷贝出去了,就是新建了几个对象
delete qq;
ss->Display();
delete ss;
return 0;
}
运行结果如下:
实现结果