原型(Prototype)模式
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。
优点:
复制自身。客户不知道需要对象的实际类型,只需知道它的抽象基类即可。(即有继承树的情况)
缺点:
必须先有一个对象实例(即原型)才能clone。
示例一
“深拷贝”例子
#include <iostream> using namespace std; // 原型模式,本质就是深拷贝 // 深拷贝,正确的原型模式 class PrototypeRight { private: int a; int *p; // 有一个指针 public: PrototypeRight() { a = 3; p = new int(2); } // 不使用默认的拷贝构造函数! PrototypeRight(const PrototypeRight& obj) { a = obj.a; p = new int(*obj.p); } void outputPointerAddress() { cout << p << endl; } ~PrototypeRight() { delete p; } }; int main() { // 这一部分是正确的原型模式的测试样例 PrototypeRight p1; PrototypeRight p2 = p1; p1.outputPointerAddress(); p2.outputPointerAddress(); return 0; } // 0x580f28 // 0x580fa8
可见指针值不同了,说明指向了不同的空间。
示例二
原型模式实现的关键就是实现Clone函数,对于C++来说,其实就是拷贝构造函数,需实现深拷贝,下面给出一种实现。
/* 原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 Created by Phoenix_FuliMa */ #include <iostream> #include <string> using namespace std; class Prototype { public: virtual Prototype *Clone() = 0; virtual void display() = 0; }; class Prototype1:public Prototype { protected: string name; int id; public: Prototype1(string name, int id) { this->name = name; this->id = id; } Prototype1(const Prototype1&type) { this->name = type.name; this->id = type.id; } virtual void display() { cout<<"my name and id are : " << this->id<<" "<< this->name <<endl; } Prototype *Clone() { return new Prototype1(*this); } }; class Prototype2:public Prototype { protected: string name; public: Prototype2(string name) { this->name = name; } Prototype2(const Prototype2&type) { this->name = type.name; } virtual void display() { cout<<"my name is : "<< this->name <<endl; } Prototype *Clone() { return new Prototype2(*this); } }; int main() { Prototype *obj1 = new Prototype1("mafuli", 1); Prototype *obj2 = obj1->Clone(); Prototype *obj3 = obj2->Clone(); obj1->display(); obj2->display(); obj3->display(); Prototype *obj4 = new Prototype2("fulima"); Prototype *obj5 = obj4->Clone(); Prototype *obj6 = obj5->Clone(); obj4->display(); obj5->display(); obj6->display(); delete obj1; delete obj2; delete obj3; delete obj4; delete obj5; delete obj6; system("pause"); return 0; } /* my name and id are : 1 mafuli my name and id are : 1 mafuli my name and id are : 1 mafuli my name is : fulima my name is : fulima my name is : fulima */
原文:http://www.cnblogs.com/jeakeven/p/4937365.html