C++二十三种设计模式之原型模式
C++二十三种设计模式之原型模式
- 一、组成
- 二、特点
- 三、目的
- 四、缺点
- 五、示例代码
一、组成
抽象原型类:声明克隆接口。
具体原型类:实现克隆接口。
二、特点
1、通过具体原型类克隆的对象只是部分属性值不同。
2、克隆函数内部可用拷贝构造函数赋值。
三、目的
通过已有对象来复制新对象,不同对象之间仅部分属性有差异。
四、缺点
1、场景限制问题,如果对象内部存在循环引用或动态分配的资源会比较麻烦。
2、深拷贝和浅拷贝问题,对象有嵌套结构则需要复杂的深拷贝逻辑。
五、示例代码
#include<iostream>
#include <vector>
#include <list>
#include <string>
#include <mutex>
#include <map>
#include<stack>
using namespace std;
class Prototype;//抽象原型类
class BaseCharacter;//抽象类
class Player;//具体原型类
class Enemy;//具体原型类
class Prototype {
public:
Prototype() {}
virtual shared_ptr<Prototype> clone() = 0;
virtual void setHealth(int health) = 0;
virtual void setAttack(int attack) = 0;
virtual void setDefense(int defense) = 0;
virtual void setName(string name) = 0;
virtual void print() = 0;
};
class BaseCharacter : public Prototype {
public:
BaseCharacter() {}
BaseCharacter(string name, int health, int attack, int defense) :m_name(name), m_health(health), m_attack(attack), m_defense(defense) {};
void setHealth(int health) {
m_health = health;
};
void setAttack(int attack) {
m_attack = attack;
};
void setDefense(int defense) {
m_defense = defense;
};
void setName(string name) {
m_name = name;
};
void print() {
cout << "name:" << m_name << ",health:" << m_health << endl;
}
protected:
int m_health;
int m_attack;
int m_defense;
string m_name;
};
class Player : public BaseCharacter {
public:
Player(string name, int health, int attack, int defense) : BaseCharacter(name, health, attack, defense) {};
~Player() {
cout << "~Player " << m_name << endl;
}
shared_ptr<Prototype> clone() {
return make_shared<Player>(*this);
};
};
class Enemy : public BaseCharacter {
public:
Enemy(string name, int health, int attack, int defense) : BaseCharacter(name, health, attack, defense) {};
~Enemy() {
cout << "~Enemy " << m_name << endl;
}
shared_ptr<Prototype> clone() {
return make_shared<Enemy>(*this);
};
};
void test() {
auto player1 = make_shared<Player>("Player1", 1, 2, 3);
player1->setHealth(100);
auto player2 = player1->clone();
player2->setName("Player2");
player1->setHealth(1000);
player2->print();
player1->print();
}
int main() {
test();
}