/*****************************************************************//** * \file ActorMemento.h * \brief 备忘录模式 Memento Pattern亦称:快照、Snapshot、Memento C++ 14 * 2023年6月6日 涂聚文 Geovin Du Visual Studio 2022 edit. * \author geovindu * \date June 2023 *********************************************************************/ #pragma once #ifndef ACTORMEMENTO_H #define ACTORMEMENTO_H #include<cstring> #include<stdbool.h> #include<stdlib.h> #include<iostream> #include<malloc.h> #include<cmath> #include <iostream> #include <sstream> #include <vector> #include <algorithm> #include <array> #include <functional> #include <list> #include <string> #include <string.h> #include <vector> #include <map> using namespace std; namespace DuMementoPattern { /// <summary> /// /// </summary> class ActorMemento { private: // /// <summary> /// 构造函数,用private修饰以防止在外部被随意创建 /// </summary> /// <param name="life"></param> /// <param name="magic"></param> /// <param name="face"></param> ActorMemento(int life, int magic, int face) :mLife(life), mMagic(magic), mfaceScore(face) {} private: //提供一些供Fighter类来访问的接口,用private修饰防止被任意类访问 /// <summary> /// 友元类Fighter可以访问本类的私有成员函数 /// </summary> friend class ActorFighter; /// <summary> /// /// </summary> /// <returns></returns> int getLife() const { return mLife; } /// <summary> /// /// </summary> /// <param name="life"></param> void setLife(int life) { mLife = life; } /// <summary> /// /// </summary> /// <returns></returns> int getMagic() const { return mMagic; } /// <summary> /// /// </summary> /// <param name="magic"></param> void setMagic(int magic) { mMagic = magic; } /// <summary> /// /// </summary> /// <returns></returns> int getFaceScore() const { return mfaceScore; } /// <summary> /// /// </summary> /// <param name="face"></param> void getFaceScore(int face) { mfaceScore = face; } private: /// <summary> /// 生命值 /// </summary> int mLife; /// <summary> /// 魔法值 /// </summary> int mMagic; /// <summary> /// 颜值 /// </summary> int mfaceScore; }; } #endif /*****************************************************************//** * \file ActorFighter.h * \brief 备忘录模式 Memento Pattern亦称:快照、Snapshot、Memento C++ 14 * 2023年6月6日 涂聚文 Geovin Du Visual Studio 2022 edit. * \author geovindu * \date June 2023 *********************************************************************/ #pragma once #ifndef ACTORFIGHTER_H #define ACTORFIGHTER_H #include<cstring> #include<stdbool.h> #include<stdlib.h> #include<iostream> #include<malloc.h> #include<cmath> #include <iostream> #include <sstream> #include <vector> #include <algorithm> #include <array> #include <functional> #include <list> #include <string> #include <string.h> #include <vector> #include <map> #include "ActorMemento.h" using namespace std; namespace DuMementoPattern { /// <summary> /// /// </summary> class ActorFighter { public: /// <summary> /// 构造函数 /// </summary> /// <param name="life"></param> /// <param name="magic"></param> /// <param name="face"></param> ActorFighter(int life, int magic, int face) :mLife(life), mMagic(magic), mfaceScore(face) {} public: /// <summary> /// 将数据写入备忘录(创建备忘录,并在其中存储了当前状态) /// </summary> /// <returns></returns> ActorMemento* createMomento() { return new ActorMemento(mLife, mMagic, mfaceScore); } /// <summary> /// 从备忘录中恢复玩家数据 /// </summary> /// <param name="pfm"></param> void restoreMomento(ActorMemento* pfm) { mLife = pfm->getLife(); mMagic = pfm->getMagic(); mfaceScore = pfm->getFaceScore(); } /// <summary> /// 为测试目的引入的接口,设置生命值为0 /// </summary> void setToDead() { mLife = 0; } /// <summary> /// 用于输出一些信息 /// </summary> void displayInfo() { cout << "主角当前的生命值、魔法值、颜值分别为:" << mLife << "," << mMagic << "," << mfaceScore << endl; } private: //角色属性 /// <summary> /// 生命值 /// </summary> int mLife; /// <summary> /// 魔法值 /// </summary> int mMagic; /// <summary> /// 颜值 /// </summary> int mfaceScore; //......其他数据略 }; } #endif /*****************************************************************//** * \file ActorCareTaker.h * \brief 备忘录模式 Memento Pattern亦称:快照、Snapshot、Memento C++ 14 * 2023年6月6日 涂聚文 Geovin Du Visual Studio 2022 edit. * \author geovindu * \date June 2023 *********************************************************************/ #pragma once #ifndef ACTORCARETAKER_H #define ACTORCARETAKER_H #include<cstring> #include<stdbool.h> #include<stdlib.h> #include<iostream> #include<malloc.h> #include<cmath> #include <iostream> #include <sstream> #include <vector> #include <algorithm> #include <array> #include <functional> #include <list> #include <string> #include <string.h> #include <vector> #include <map> #include "ActorMemento.h" using namespace std; namespace DuMementoPattern { /// <summary> /// 管理者(负责人)类 /// </summary> class ActorCareTaker { public: /// <summary> /// 构造函数 /// </summary> /// <param name="ptmpfm"></param> ActorCareTaker(ActorMemento* ptmpfm) :m_pfm(ptmpfm) {} //形参是指向备忘录对象的指针 /// <summary> /// 获取指向备忘录对象的指针 /// </summary> /// <returns></returns> ActorMemento* getMemento() { return m_pfm; } /// <summary> /// 保存指向备忘录对象的指针 /// </summary> /// <param name="ptmpfm"></param> void setMemento(ActorMemento* ptmpfm) { m_pfm = ptmpfm; } private: ActorMemento* m_pfm; //指向备忘录对象的指针 }; } #endif /*****************************************************************//** * \file MultipleSnapshotsCareTaker.h * \brief 备忘录模式 Memento Pattern亦称:快照、Snapshot、Memento C++ 14 * 2023年6月6日 涂聚文 Geovin Du Visual Studio 2022 edit. * \author geovindu * \date June 2023 *********************************************************************/ #pragma once #ifndef MULTIPLESNAPSHOTSCARETAKER_H #define MULTIPLESNAPSHOTSCARETAKER_H #include<cstring> #include<stdbool.h> #include<stdlib.h> #include<iostream> #include<malloc.h> #include<cmath> #include <iostream> #include <sstream> #include <vector> #include <algorithm> #include <array> #include <functional> #include <list> #include <string> #include <string.h> #include <vector> #include <map> #include "ActorMemento.h" using namespace std; namespace DuMementoPattern { /// <summary> /// 支持多个快照的负责人(管理者)类 /// </summary> class MultipleSnapshotsCareTaker { public: /// <summary> /// 析构函数用于释放资源 /// </summary> ~MultipleSnapshotsCareTaker() { for (auto iter = m_pfmContainer.begin(); iter != m_pfmContainer.end(); ++iter) { delete (*iter); } //end for } /// <summary> /// 保存指向备忘录对象的指针 /// </summary> /// <param name="ptmpfm"></param> void setMemento(ActorMemento* ptmpfm) { m_pfmContainer.push_back(ptmpfm); } /// <summary> /// 获取指向备忘录对象的指针 /// </summary> /// <param name="index"></param> /// <returns></returns> ActorMemento* getMemento(int index) { auto iter = m_pfmContainer.begin(); for (int i = 0; i <= index; ++i) { if (i == index) return (*iter); else ++iter; } //end for return NULL; } private: /// <summary> /// 存储备忘录对象指针的容器 /// </summary> vector<ActorMemento*> m_pfmContainer; //#include <vector> }; } #endif /*****************************************************************//** * \file GeovinDu.h * \brief 备忘录模式 Memento Pattern亦称:快照、Snapshot、Memento C++ 14 * 2023年6月6日 涂聚文 Geovin Du Visual Studio 2022 edit. * \author geovindu * \date June 2023 *********************************************************************/ #pragma once #ifndef GEOVINDU_H #define GEOVINDU_H #include<cstring> #include<stdbool.h> #include<stdlib.h> #include<iostream> #include<malloc.h> #include<cmath> #include <iostream> #include <sstream> #include <vector> #include <algorithm> #include <array> #include <functional> #include <list> #include <string> #include <string.h> #include <vector> #include <map> #include "ActorCareTaker.h" #include "ActorFighter.h" #include "ActorMemento.h" #include "MultipleSnapshotsCareTaker.h" using namespace std; namespace DuMementoPattern { /// <summary> /// /// </summary> class GeovinDu { private: public: /// <summary> /// /// </summary> void displaySimple(); /// <summary> /// /// </summary> void displayDuSimple(); }; } #endif /*****************************************************************//** * \file GeovinDu.cpp * \brief 备忘录模式 Memento Pattern亦称:快照、Snapshot、Memento C++ 14 * 2023年6月6日 涂聚文 Geovin Du Visual Studio 2022 edit. * \author geovindu * \date June 2023 *********************************************************************/ #include "GeovinDu.h" using namespace std; namespace DuMementoPattern { /// <summary> /// /// </summary> void GeovinDu::displaySimple() { DuMementoPattern::ActorFighter* p_fighter = new DuMementoPattern::ActorFighter(800, 200, 300); //(1)显示玩家主角在与BOSS战斗之前的信息 p_fighter->displayInfo(); //(2)为玩家主角类对象创建一个备忘录对象(其中保存了当前主角类对象中的必要信息) //_nmsp1::FighterMemento* p_fighterMemo = p_fighter->createMomento(); DuMementoPattern::ActorCareTaker* pfcaretaker = new DuMementoPattern::ActorCareTaker(p_fighter->createMomento()); //(3)玩家与BOSS开始战斗 cout << "主角与BOSS开始进行激烈的飙戏------" << endl; p_fighter->setToDead(); //主角在与BOSS战斗中,生命值最终变成0而死亡(被BOSS击败) p_fighter->displayInfo(); //显示玩家主角在与BOSS战斗之后的信息 //(4)因为在与BOSS战斗之前已经通过NPC保存了游戏进度,这里模拟载入游戏进度,恢复玩家主角类对象的数据,让其可以与BOSS再次战斗 cout << "主角通过备忘录恢复自己的信息------" << endl; //p_fighter->restoreMomento(p_fighterMemo); p_fighter->restoreMomento(pfcaretaker->getMemento()); p_fighter->displayInfo(); //显示玩家主角通过备忘录恢复到战斗之前的信息 //(5)释放资源 //delete p_fighterMemo; delete pfcaretaker->getMemento(); delete pfcaretaker; //新增 delete p_fighter; } /// <summary> /// /// </summary> void GeovinDu::displayDuSimple() { DuMementoPattern::ActorFighter* p_fighter2 = new DuMementoPattern::ActorFighter(800, 200, 300); DuMementoPattern::MultipleSnapshotsCareTaker* pfcaretaker2 = new DuMementoPattern::MultipleSnapshotsCareTaker(); pfcaretaker2->setMemento(p_fighter2->createMomento()); //做第一次快照吗,此快照玩家生命值为800 p_fighter2->setToDead(); //改变玩家主角的生命值 pfcaretaker2->setMemento(p_fighter2->createMomento()); //做第二次快照,此快照玩家生命值为0 p_fighter2->displayInfo(); //玩家主角生命值应该为0 cout << "------------------" << endl; //当前玩家生命值为0,恢复第一次快照,也就是恢复玩家生命值为800 p_fighter2->restoreMomento(pfcaretaker2->getMemento(0)); p_fighter2->displayInfo(); //玩家主角生命值应该恢复为800 //释放资源 delete p_fighter2; delete pfcaretaker2; } }
调用:
/*****************************************************************//** * \file ConsoleDuMementoPattern.cpp * \brief 备忘录模式 Memento Pattern亦称:快照、Snapshot、Memento C++ 14 * 2023年6月6日 涂聚文 Geovin Du Visual Studio 2022 edit. * \author geovindu * \date June 2023 *********************************************************************/ // ConsoleDuMementoPattern.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #define _UNICODE #include <iostream> #include "GeovinDu.h" using namespace std; using namespace DuMementoPattern; int main() { std::cout << "Hello World!涂聚文 Geovin Du\n"; GeovinDu geovin; geovin.displaySimple(); cout << "**********" << endl; geovin.displayDuSimple(); system("pause"); return 0; } // 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单 // 调试程序: F5 或调试 >“开始调试”菜单 // 入门使用技巧: // 1. 使用解决方案资源管理器窗口添加/管理文件 // 2. 使用团队资源管理器窗口连接到源代码管理 // 3. 使用输出窗口查看生成输出和其他消息 // 4. 使用错误列表窗口查看错误 // 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目 // 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件 #define UNICODE
输出:
Hello World!涂聚文 Geovin Du 主角当前的生命值、魔法值、颜值分别为:800,200,300 主角与BOSS开始进行激烈的飙戏------ 主角当前的生命值、魔法值、颜值分别为:0,200,300 主角通过备忘录恢复自己的信息------ 主角当前的生命值、魔法值、颜值分别为:800,200,300 ********** 主角当前的生命值、魔法值、颜值分别为:0,200,300 ------------------ 主角当前的生命值、魔法值、颜值分别为:800,200,300 请按任意键继续. . .