原型模式

前言

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

当你需要从A的实例得到一份与A内容相同,但是又互不干扰的实例的话,就需要使用原型模式。

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。这个其实和C++的拷贝构造函数的作用是相似的(但不相同),实际上就是动态抽取当前对象运行时的状态。

当然有的时候,如果我们并不需要基于现有的对象复制新的对象,或者我们需要的就是一个干净的空对象,那就用工厂模式或者抽象工厂模式。

为什么需要原型模式?

1. 为什么不用new直接新建对象,而要用原型模式?

用new新建对象不能获取当前对象运行时的状态,其次就算new了新对象,在将当前对象的值复制给新对象,效率也不如原型模式高。

2. 为什么不直接使用拷贝构造函数,而要使用原型模式?

原型模式与拷贝构造函数是不同的概念,拷贝构造函数涉及的类是已知的,原型模式涉及的类可以是未知的(基类的拷贝构造函数只能复制得到基类的对象)。

原型模式生成的新对象可能是一个派生类。拷贝构造函数生成的新对象只能是类本身。原型模式是描述了一个通用方法(或概念),它不管是如何实现的,而拷贝构造则是描述了一个具体实现方法。

Derived d;
Base &b = d;
Derived d2(b); // 试图用b所指向的d来复制构造出一个新的d2,但这是不可以的,因为b的类型是Base,而不是Derived。

UML

 

#include <iostream>

class CBase
{
public:
    CBase() {}
    virtual ~CBase() {}
    virtual CBase* clone()
    {
        return new CBase(*this);
    }
};

class CDerive : public CBase
{
public:
    CDerive(int a): m_ia(a) {}
    ~CDerive() {}

    CBase * clone()
    {
        return new CDerive(*this);
    }
    
    int m_ia;
};


int main()
{
    CDerive d(8);
    CBase &b = d;
    CDerive* d2 = dynamic_cast<CDerive*>(b.clone());

    std::cout << d2->m_ia << '\n';

    delete d2;

    return 0;
}

 

posted @ 2019-03-05 15:01  二狗啸地  阅读(180)  评论(0编辑  收藏  举报