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

原型模式

用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象。
本文使用书中简历复印事例,代码使用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、深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ThomasKUI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值