您的位置:首页 > 其它

原型模式

2019-06-12 18:10 1111 查看

原型模式比较简单,其作用就是为每一个对象提供一个接口,使这些对象具有自我复制的功能。

既然要实现对象的复制,就会涉及到深拷贝和浅拷贝。

代码上,小妖怪。

#include<iostream>
#include<string>
#include<cstring>

using namespace std;

class Object
{
public:
virtual Object* clone() = 0;

//↓↓↓↓这个不是必要的,只是为了方便演示
public:
virtual void print() = 0;
};

class GameSlime : public Object
{
public:
GameSlime():m_STR(-1),m_AGI(-1),m_VIT(-1),m_INT(-1),
m_DEX(-1),m_CON(-1),m_LUK(-1),m_ATK(-1),m_HP(-1)
{
m_name = NULL;
}
GameSlime(int STR,int AGI,int VIT,int INT,int DEX,
int CON,int LUK,int ATK,int HP,const char* name)
:m_STR(STR),m_AGI(AGI),m_VIT(VIT),m_INT(INT),
m_DEX(DEX),m_CON(CON),m_LUK(LUK),m_ATK(ATK),m_HP(HP)
{
if(name!=NULL)
{
m_name = static_cast<char*>(calloc(0,strlen(name)+1));
if(m_name!=NULL)
strcpy(m_name,name);
}
}
~GameSlime()
{
if(m_name!=NULL)
free(m_name);
cout<<"~GameSlime()"<<endl;
}

void Injured(int i)
{
if(i<=0) return;
if(i >= m_HP)
m_HP = 0;
else
m_HP -= i;

}

virtual Object* clone()
{
//深拷贝
GameSlime* obj = new GameSlime();
*obj = *this;
obj->m_name = static_cast<char*>(calloc(0,strlen(this->m_name)+1));
if(obj->m_name!=NULL)
strcpy(obj->m_name,this->m_name);

return obj;
}

virtual void print()
{
//        cout << "STR:"<<m_STR<<endl;
//        cout << "AGI:"<<m_AGI<<endl;
//        cout << "VIT:"<<m_VIT<<endl;
//        cout << "INT:"<<m_INT<<endl;
//        cout << "DEX:"<<m_DEX<<endl;
//        cout << "CON:"<<m_CON<<endl;
//        cout << "LUC:"<<m_LUK<<endl;
//        cout << "ATK:"<<m_ATK<<endl;
cout << "HP :"<<m_HP <<endl;
cout << "name:"<< m_name<<endl;

1c013
cout << endl;
}

private:
int m_STR;  //力量
int m_AGI;  //敏捷
int m_VIT;  //耐力
int m_INT;  //智力
int m_DEX;  //灵巧
int m_CON;  //体质
int m_LUK;  //幸运
int m_ATK;  //攻击力
int m_HP;   //血量

char* m_name; //名字
};

int main()
{
//突然出现一个精英史莱姆
GameSlime slime1(1,1,1,1,1,1,1,1,1000,"Elite slame");
cout<<"slime1"<<endl;
slime1.print();

//精英史莱姆被太阳灼烧而掉血
slime1.Injured(100);
cout<<"slime1"<<endl;
slime1.print();

//精英史莱姆被玩家攻击而掉血
slime1.Injured(200);
cout<<"slime1"<<endl;
slime1.print();

//精英史莱姆因为张大仙直播间被封内心悲痛欲绝而掉血
slime1.Injured(300);
cout<<"slime1"<<endl;
slime1.print();

cout<<"***************************************"<<endl;

//精英史莱姆自我复制
GameSlime* slime2 = static_cast<GameSlime*>(slime1.clone());
cout<<"slime2"<<endl;
slime2->print();

cout<<"slime1"<<endl;
slime1.print();

delete slime2;

return 0;
}

上面的代码通过一个史莱姆分裂的例子演示了原型模式。
实际项目中,某个类通过长时间的运行后,其状态是不可测的,但是我们又需要一个和这个类一模一样状态的类,我们不可能重新创建一个类让他运行相同时间吧,即使运行了相同的时间也有可能得到的是不一样状态的类。这就是原型模式诞生的初衷。

有人可能会说,原型模式和拷贝构造函数实现的功能不是一样吗?那有必要使用这个设计模式吗?

让我们来分析分析原型模式和拷贝构造函数。
相同点:原型模式和拷贝构造函数都是要产生对象的复制品。
不同点:原型模式实现的是一个clone接口,注意是接口,也就是基于多态的clone虚函数。也就是说原型模式能够通过基类指针来复制派生类对象。拷贝构造函数完不成这样的任务。

原型模式的核心是克隆,构造函数只是克隆的一个办法而已,这大概就是原型模式的魅力了吧。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: