定义

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


结构



理解

1. Prototype是原型基类,提供Clone纯虚方法,它根据不同的派生类来克隆不同的对象。

2. ConcretePrototype是原型具体类。实现Clone方法,克隆自己,返回克隆后的新对象。

3. Client调用基类Clone接口,就可以得到一个克隆对象。


要点

1. 原型模式中,Client并不知道要克隆对象的实际类型,只需知道基类类型即可。

2. 克隆对象比直接创建对象的优点在于,克隆是将原有对象的行为属性带到了新的对象中。

3. C++没有克隆方法,要克隆一个对象,需要借助拷贝构造函数(Copy Constructor)来实现。拷贝构造函数中实现拷贝对象有浅拷贝和深拷贝:

浅拷贝是指对象复制时,只是对于对象中的数据成员进行值拷贝;深拷贝是指对象赋值时,对于对象的简单数据成员进行值拷贝,对于对象中的动态成员(堆或者其他系统资源),要重新分配动态空间。

当类不定义拷贝构造函数的时候,编译器会自动生一个构造函数,叫做默认拷贝构造函数。默认拷贝构造函数使用浅拷贝方式。如果类中含有动态数据成员,就必须使用深拷贝方式实现拷贝构造函数,否则,在销毁对象时,两个对象的析构函数将对同一个内存空间释放两次,产生运行时错误。


应用

源码中,Line是原型基类,具体克隆类是直线和曲线。


源码

#include <iostream>

#include <string>

using namespace std;


//原型基类. 线条

class CLinePrototype

{

public:

virtual ~CLinePrototype(){};


virtual CLinePrototype* Clone() = 0;

};


//原型具体类. 直线

class CBeelinePrototype : public CLinePrototype

{

public:

CBeelinePrototype(){};

//拷贝构造函数

CBeelinePrototype(const CBeelinePrototype &o)

{

this->m_iWeight = o.m_iWeight;

}


virtual ~CBeelinePrototype(){};


virtual CLinePrototype* Clone()

{

cout << "clone a line" << endl;

return new CBeelinePrototype(*this);

}


void SetWeight(const int &iWeight)

{

this->m_iWeight = iWeight;

}

void Print()

{

cout << "beeline weight: " << m_iWeight << endl;

}


protected:

int m_iWeight;

};


//原型具体类. 曲线

class CCurvePrototype : public CLinePrototype

{

public:

CCurvePrototype(){};

//拷贝构造函数

CCurvePrototype(const CCurvePrototype &o)

{

this->m_strType = o.m_strType;

}


virtual ~CCurvePrototype(){};


virtual CLinePrototype* Clone()

{

cout << "clone a curve" << endl;

return new CCurvePrototype(*this);

}


void SetType(const string &m_strType)

{

this->m_strType = m_strType;

}

void Print()

{

cout << "beeline type: " << m_strType.c_str() << endl;

}


protected:

string m_strType;

};


//Client

CLinePrototype* Clone(CLinePrototype* pPrototype)

{

return pPrototype->Clone();

}



int main()

{

CBeelinePrototype* p1 = new CBeelinePrototype();

p1->SetWeight(10);

CLinePrototype* p1Clone = Clone(p1);

CBeelinePrototype* p1Clone1 = dynamic_cast<CBeelinePrototype*>(p1Clone);

p1Clone1->Print();


CCurvePrototype* p2 = new CCurvePrototype();

p2->SetType("DOT");

CLinePrototype* p2Clone = Clone(p2);

CCurvePrototype* p2Clone1 = dynamic_cast<CCurvePrototype*>(p2Clone);

p2Clone1->Print();


system("pause");

return 0;

}


输出:

clone a line

beeline weight: 10

clone a curve

beeline type: DOT