您的位置:首页 > 编程语言 > C语言/C++

C++设计模式(六)—原型模式

2018-04-02 12:02 253 查看

原型模式

用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象。


本文使用书中简历复印事例,代码使用C++语言描述,代码存在的不足或问题有望各位指出。

(1)我们首先看一下原型模式的代码框架

#include <iostream>
#include <string>
using namespace std;
//原型类
class Prototype
{
public:
Prototype(){}
virtual ~Prototype(){}
virtual Prototype *Clone()=0;
virtual string get() =0;

};

//具体原型类
class ConcretePrototype : public Prototype
{
public:
ConcretePrototype(string id) :id(id)
{
}
ConcretePrototype(const ConcretePrototype &conPro) :id (conPro.id)
{
}
~ConcretePrototype(){}
Prototype *Clone() override
{
return new ConcretePrototype(*this);
}
string get() override
{
return id;
}
private:
string id;
};

int main ()
{
Prototype *p1 = new ConcretePrototype("I");
Prototype *p2 =p1->Clone();
cout << p2->get() <<endl;
delete p1;
delete p2;
return 0;
}


原型模式其实就是从一个对象在创建另外一个可定制的对象,而且不需知道任何创建的细节。

(2)简历事例使用原型模式来实现

#include <iostream>
#include <string>
using namespace std;

class Prototype
{
public:
Prototype(){}
virtual ~Prototype(){}
virtual Prototype *Clone()=0;
virtual void setWorkExperience(string timeArea, string company)=0;
virtual void setPersonalInfo(string sex, string age)=0;
virtual void display() =0;
};
//简历类
class Resume : public Prototype
{
public:
Resume (string name):name(name)
{}
Resume (const Resume& resume): name(resume.name),sex(resume.sex),age(resume.age),timeArea(resume.timeArea),company(resume.company)
{}
//设置个人信息
void setPersonalInfo(string sex, string age) override
{
this->sex =sex;
this->age =age;
}
//设置工作经历
void setWorkExperience(string timeArea, string company) override
{
this->timeArea = timeArea;
this ->company =company;
}
//显示
void display() override
{
cout<< name << " " << sex << " " << age << " " << endl;
cout<< timeArea << " " << company << endl;
}
virtual Prototype *Clone() override
{
return new Resume(*this);
}
private:
string name;
string sex;
string age;
string timeArea;
string company;
};

int main()
{
Prototype *p1 = new Resume("小刘");
p1->setPersonalInfo("男","25");
p1->setWorkExperience("1998-2000","xx公司");
Prototype *p2 = p1->Clone();                  //只需要调用Clone方法就可以实现新简历的生成,
p2->setWorkExperience("1998-2006","YY企业");    //并且可以在修改新简历的细节
Prototype *p3 = p1->Clone();
p3->setPersonalInfo("男","28");
p1->display();
p2->display();
p3->display();
delete p1;
delete p2;
delete p3;
return 0;

}


(3)深拷贝和浅拷贝的实现,本例注释代码部分为浅拷贝实现,例中主要展示深拷贝实现。

#include <iostream>
#include <string>
using namespace std;

//简历类
class Prototype
{
public:
Prototype(){}
virtual ~Prototype(){}
virtual Prototype *Clone()=0;
virtual void setWorkExperience(string timeArea, string company){}
virtual void setPersonalInfo(string sex, string age){}
virtual void display(){}
};

class WorkExperiment:public Prototype
{
public:
WorkExperiment(){}
~WorkExperiment(){}
WorkExperiment (const WorkExperiment& wo)
{
workDate =wo.workDate;
company = wo.company;
}
WorkExperiment *Clone() override   //工作经历类实现克隆方法
{
return new WorkExperiment(*this);
}
string getDate()
{
return workDate;
}
string getCom()
{
return company;
}
void setDate(string workDate)
{
this->workDate = workDate;
}
void setCom(string company)
{
this->company = company;
}
private:
string workDate;
string company;

};

class Resume : public Prototype
{
public:
Resume(){}
~Resume()
{
delete work;
}
Resume (string name):name(name)
{
work=new WorkExperiment();
}
Resume (const Resume& resume)
{
name = resume.name;    //浅拷贝调用
sex = resume.sex;
age = resume.age;
work =resume.work;   //指向同一块内存(浅拷贝)

}
void setPersonalInfo(string sex, string age) override
{
this->sex =sex;
this->age =age;
}
void setWorkExperience(string workDate, string company) override
{
work->setDate(workDate);
work->setCom (company);
}

void display() override
{
cout<< name << " " << sex << " " << age << " " << endl;
cout<< work->getDate() << " " << work->getCom() << endl;
}
Prototype *Clone() override
{
Resume *obj =new Resume(this->work);   //深拷贝实现
obj->name =this->name;       //调用私有的构造方法,让工作经历克隆完成,
obj->sex = this->sex;        //然后再给这个简历对象的相关字段赋值,最终返回一个深复制的简历对象
obj->age = this->age;
return obj;

//      return new Resume( *this);         //浅拷贝调用
}
private:
Resume(WorkExperiment *work)
{
this->work = work->Clone();   //提供Clone方法调用的私有构造函数,以便克隆工作经历的数据
}
string name;
string sex;
string age;
string timeArea;
string company;
WorkExperiment *work;
};

int main()
{
Prototype *p1 = new Resume("小刘");
p1->setPersonalInfo("男","25");
p1->setWorkExperience("1998-2000","xx公司");
Prototype *p2 = p1->Clone();
p2->setWorkExperience("1998-2006","YY企业");
Prototype *p3 = p1->Clone();
p3->setPersonalInfo("男","28");
p1->display();
p2->display();
p3->display();
delete p1;
delete p2;
delete p3;
return 0;

}


1、使用深拷贝可以实现三次显示的结果各不同的要求,如果使用浅拷贝,则工作经历work指向同一块内存,则最终显示的工作经历三个均与最后一个相同。

2、深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式 c++