/*****************************************************************//** * \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 請按任意鍵繼續. . .