使用原型实例指定创建对象的种类,通过拷贝这些原型来创建新的对象。
原型模式也是一种特殊的abstract factory,他的使用情况是,对象比较复杂(难以用工厂模式实现,或者希望保留开发的中间状态),如果初始的状态不太让人满意,那么等到已经开发出一个比较好的状态时,去clone()一个比较满意对象的状态。
要求跟之前的工厂模式一样又比较稳定的接口(泛用参数来创建对象),还是不用new,而是去使用clone()的方法去创建新的对象。
ps:c++的序列化太难了.jpg,但是有拷贝构造函数所以很nice
pss:原型对象不是供你使用的,是供你clone()用的!!!
下面的代码是一个生成不同小怪的测试程序。
#pragma once
#include <iostream>
using namespace std;
//深拷贝为了避免内存泄露,拥有指针成员的对象进行拷贝的时候,需要自己定义拷贝构造函数,使拷贝后的对象指针成员拥有自己的内存地址
//含有指针的对象在拷贝的时候,如果使用默认的拷贝构造函数,会导致前后指针指向同一个东西,造成了内存泄漏,我们需要的是值拷贝(包括指针指向的值)
//拷贝构造的参数必须是引用形式&,否则会产生循环调用,咱建议未来的自己好好看下深拷贝怎么写
template<typename T>
class Monster_prototype_base {
protected:
string name;
int atk;
int def;
int life_point;
public:
Monster_prototype_base(string str, int att, int dee, int life_points) :name(str), atk(att), def(dee), life_point(life_points) {}
virtual Monster_prototype_base<T>* clone() = 0;
virtual ~Monster_prototype_base() {}
virtual void describe() {}
void summon() {
describe();
cout << " name: " << name << " atk: " << atk << " def: " << def << " life_point: " << life_point;
cout << endl;
}
};
template<typename T>
class magic_enemy :public Monster_prototype_base<T> {
public:
virtual void describe() {
cout << "One Magic_enemy!";
}
magic_enemy(string str, int atk, int def, int life_point) :Monster_prototype_base<T>(str, atk, def, life_point) {}
virtual Monster_prototype_base<T>* clone() {
return new magic_enemy(*this);
}
};
template<typename T>
class phy_enemy :public Monster_prototype_base<T> {
public:
virtual void describe() {
cout << "One phy_enemy!";
}
phy_enemy(string str, int atk, int def, int life_point) :Monster_prototype_base<T>(str, atk, def, life_point) {}
virtual Monster_prototype_base<T>* clone() {
return new phy_enemy(*this);
}
};
接口
//测试原型prototype模式
cout << "测试原型模式" << endl;
magic_enemy<bool>* Hana = new magic_enemy<bool>("Hana", 1500, 1000, 1);
auto Hana_1 = Hana->clone();
phy_enemy<bool>* Doge = new phy_enemy<bool>("Doge",1000,1500,1);
auto Doge_1 = Doge->clone();
Hana_1->summon();
Doge_1->summon();
Hana->summon();//看看有没有被浅拷贝害了
Doge->summon();