创建型模式--6.原型模式【杰尔马66】

1. 克隆人

在海贼王世界中,杰尔马王国拥有一支强大的科学作战部队 – 杰尔马66军团,其先锋是文斯莫克家族,他们作为雇佣军活跃在世界各地。

这支部队战斗力强悍,没有情感,不畏生死,勇往直前。从某种意义上来讲,他们不能被称之为人,因为他们是科学的结晶,他们都出自文斯莫克·伽治之手。
在这里插入图片描述

伽治曾和海贼世界中的顶级科学家贝加庞克是同事,一起发现了血统因子,于是才有了现在这么多的杰尔马士兵,对,你没有看错他们都是被克隆出来的。

克隆是一种最直接、最快捷的创建新对象的方式,它不仅隐藏了创建新对象的诸多细节,还保留了源对象的属性信息,保证了这两个对象能够一模一样。
在这里插入图片描述

血统因子士兵这是一个复杂而又艰辛的过程,一旦研发成功,之后的事情就是基于母体进行复制(克隆)。我猜伽治不仅是一名科学家,可能还是一位架构师,因为他懂设计模式,这种制作克隆人的模式就是原型模式

原型模式就是能够复制已有的对象,而又无需使代码依赖它们所属的类。换种说法,就是通过已有对象克隆出另一个新的对象,并且克隆这个对象不需要使用构造函数。

2. 这是在脱了裤子放屁吗

懂C++的亲们看了上面关于原型模式的描述肯定是满脑子问号。因为在C++中只要定义一个类,这个类就默认自带六大函数,其中一个就是拷贝构造函数,这个函数的作用就是通过一个已有对象克隆出一个新的对象。一个拷贝构造函数就能搞定的事情为啥还要搞出一种设计模式呢?

这是脱了裤子放屁吗?肯定不是,因为这里边还隐藏着一个细节。

  • 对于伽治来说,他可能想通过一代士兵克隆出更优秀的二代士兵
  • 对于程序猿来说,我们可能想要通父类指针或引用把指向的子类对象克隆出来
    通过这个描述,就可以从里面挖掘出一个重要的信息:克隆可能会在父类和子类之间进行,并且可能是动态的,很明显通过父类的拷贝构造函数无法实现对子类对象的拷贝,其实这就是一个多态,我们需要给父类提供一个克隆函数并且是一个虚函数

现在逻辑关系已经说明白了,来看一下对应UML类图

在这里插入图片描述

3. 量产士兵

根据上面的UML类图,我们就可以把对应的代码写出了,示例代码如下:

#include <iostream>
using namespace std;

class GermaSoldier
{
public:
    virtual GermaSoldier* clone() = 0;
    virtual string whoAmI() = 0;
    virtual ~GermaSoldier() {}
};

class Soldier66 : public GermaSoldier
{
public:
    GermaSoldier* clone() override
    {
        return new Soldier66(*this);
    }
    string whoAmI() override
    {
        return string("我是杰尔马66的超级士兵!!!");
    }
};

class Soldier67 : public GermaSoldier
{
public:
    GermaSoldier* clone()
    {
        return new Soldier67(*this);
    }
    string whoAmI() override
    {
        return string("我是杰尔马67的超级士兵!!!");
    }
};

int main()
{
    GermaSoldier* obj = new Soldier66;
    GermaSoldier* soldier = obj->clone();
    cout << soldier->whoAmI() << endl;
    delete soldier;
    delete obj;

    obj = new Soldier67;
    soldier = obj->clone();
    cout << soldier->whoAmI() << endl;
    delete soldier;
    delete obj;
}

代码中的main()函数对应的就是UML类图中的客户端角色。

  • 第41行通过父类指针克隆了子类Soldier66的对象
  • 第47行通过父类指针克隆了子类Soldier67的对象
  • 在这两个士兵子类的clone()函数体内部是通过当前子类的拷贝构造函数复制出了一个新的子类对象。

程序执行的结果如下:

我是杰尔马66的超级士兵!!!
我是杰尔马67的超级士兵!!!

通过输出的结果可以看到通过父类指针克隆子类的对象成功了。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

从入门到捕蛇者说

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

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

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

打赏作者

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

抵扣说明:

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

余额充值