首页 > 编程语言 >c/c++设计模式--备忘录模式

c/c++设计模式--备忘录模式

时间:2024-06-17 10:32:09浏览次数:21  
标签:life magic -- c++ 玩家 int attack 快照 设计模式

#include <iostream>
#include <vector>

#ifdef _DEBUG   //只在Debug(调试)模式下
#ifndef DEBUG_NEW
#define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__) //重新定义new运算符
#define new DEBUG_NEW
#endif
#endif

//#include <boost/type_index.hpp>
using namespace std;
//#pragma warning(disable : 4996) 

namespace _nmsp1
{    
    //玩家主角相关的备忘录类
    class FighterMemento
    {
    private:
        //构造函数,用private修饰以防止在外部被随意创建
        FighterMemento(int life,int magic,int attack):m_life(life), m_magic(magic), m_attack(attack) {}

    private:
        //提供一些供Fighter类访问的接口,用private修饰防止被任意类访问
        friend class Fighter; //友元类Fighter可以访问奔雷的私有成员函数
        int getLife() const { return m_life; }
        void setLife(int life) { m_life = life; }

        int getMagic() const { return m_magic; }
        void setMagic(int magic) { m_magic = magic; }

        int geAttack() const { return m_attack; }
        void setAttack(int attack) { m_attack = attack; }


    private:
        //玩家主角类中要保存起来的数据,就放到这里来
        int m_life; //生命值
        int m_magic; //魔法值
        int m_attack; //攻击力
    };

    //玩家主角类
    class Fighter
    {
    public:
        //构造函数
        Fighter(int life, int magic, int attack) :m_life(life), m_magic(magic), m_attack(attack) {}

    public:
        //将玩家数据写入备忘录(创建备忘录,并在其中存储了当前状态)
        FighterMemento* createMomento()
        {
            return new FighterMemento(m_life, m_magic, m_attack);
        }
        //从备忘录中恢复玩家数据
        void restoreMomento(FighterMemento* pfm)
        {
            m_life = pfm->getLife();
            m_magic = pfm->getMagic();
            m_attack = pfm->geAttack();
        }

        //为测试目的引入的接口,设置玩家的生命值为0(玩家死亡)
        void setToDead()
        {
            m_life = 0;
        }
        //用于输出一些信息
        void displayInfo()
        {
            cout << "玩家主角当前的生命值、魔法值、攻击力分别为:" << m_life << "," << m_magic << "," << m_attack << endl;
        }

    private:
        //角色属性
        int m_life; //生命值
        int m_magic; //魔法值
        int m_attack; //攻击力
        //.....其他数据略
    };

    //管理者(负责人)类
    class FCareTaker
    {
    public:
        //构造函数
        FCareTaker(FighterMemento* ptmpfm) :m_pfm(ptmpfm) {} //形参是指向备忘录对象的指针

        //获取指向备忘录对象的指针
        FighterMemento* getMemento()
        {
            return m_pfm;
        }
        //保存指向备忘录对象的指针
        void setMemento(FighterMemento *ptmpfm)
        {
            m_pfm = ptmpfm;
        }

    private:
        FighterMemento* m_pfm; //指向备忘录对象的指针
    };

    //------------------------
    //支持多个快照的负责人(管理者)类
    class FCareTaker2
    {
    public:
        //析构函数用于释放资源
        ~FCareTaker2()
        {
            for (auto iter = m_pfmContainer.begin(); iter != m_pfmContainer.end(); ++iter)
            {
                delete (*iter);
            }
        }

        //保存指向备忘录对象的指针
        void setMemento(FighterMemento* ptmpfm)
        {
            m_pfmContainer.push_back(ptmpfm);
        }

        //获取指向备忘录对象的指针
        FighterMemento* getMemento(int index)
        {
            auto iter = m_pfmContainer.begin();
            for (int i = 0; i <= index; ++i)
            {
                if (i == index)
                    return (*iter);
                else
                    ++iter;
            }
            return NULL;
        }

    private:
        //存储备忘录对象指针的容器
        vector<FighterMemento*> m_pfmContainer; 
    };
    
}

int main()
{
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//程序退出时检测内存泄漏并显示到“输出”窗口
    
    /*
    _nmsp1::Fighter* p_fighter = new _nmsp1::Fighter(800, 200, 300);
    //(1)显示玩家主角在与BOSS战斗之前的信息
    p_fighter->displayInfo();

    //(2)为玩家主角类对象创建一个备忘录(其中保存了当前主角类对象中的必要信息)
    //_nmsp1::FighterMemento* p_fighterMemo = p_fighter->createMomento();
    _nmsp1::FCareTaker* pfcaretaker = new _nmsp1::FCareTaker(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;
    */

    _nmsp1::Fighter* p_fighter2 = new _nmsp1::Fighter(800, 200, 300);
    _nmsp1::FCareTaker2* pfcaretaker2 = new _nmsp1::FCareTaker2();
    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;



    return 0;
}

备忘录(Memento)模式:快照模式(Snapshot),行为型模式。
//(1)一个具体实现范例
// 一般该模式还会引入一个 管理者(负责人)类,但是这并不是必须的。 FCareTaker

//(2)引入备忘录(Memento)模式
//定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,
//这样以后就可以将该对象恢复到原先保存的状态
//3种角色
//a)Originator(原发器):Fighter类。
//b)Memento(备忘录):FighterMemnto类。
//c)CareTaker(负责人/管理者):FCareTaker类。
//备忘录真正的作用并不是保存数据,而是恢复数据。

//说明:

//a)快照——并不意味着所有玩家主角类的信息都要往备忘录中保存。
//b)做快照并不要求玩家主角类中需要保存的字段都一一对应备忘录中相同的字段,备忘录中可以以
//内存流,字符串,编码(Hex编码、Base64编码)方式存储或者还原来自玩家主角类中的数据。
//数据序列化。
//c)给玩家主角类做快照并不仅仅限于一次。FCareTaker2做多次快照。给了一个范例
//d)friend
//e)更适合保存原发器对象中的一部分(不是所有)内部状态,否则采用原型模式。
//f)优点:方便回到一个特定的历史步骤。缺点:对资源的消耗。
//g)完全存储。增量存储来应付频繁做快照。 完全存储和增量存储方式结合使用。Redis,RDB(完全备份),AOF(增量备份)。
//减少需要记录的数据。
//h)应用场合:下棋悔棋,保存历史记录,做快照。
//i)数据保存在内存中以及从内存中恢复数据。

标签:life,magic,--,c++,玩家,int,attack,快照,设计模式
From: https://www.cnblogs.com/bwbfight/p/18251892

相关文章

  • 升级到.Net 8 api 返回JObject 对象为空字符串
    在使用dotnet8过程中,使用了JObject类型作为api的返回,但是返回的空数组api:[HttpGet("voices")]publicasyncTask<IActionResult>GetObject(){JObjectobj=newJObject();obj["test"]="test";returnnewJsonResult(obj){StatusCod......
  • QILSTE LED灯珠 发光二极管LED H11-F312QLB/5M
    型号H11-F312QLB/5M,以其3.2x1.25x1.1mm的紧凑尺寸,在LED技术领域中占据一席之地。这款高亮蓝光LED,搭载透明平面胶体,不仅在色彩表现上纯净自然,更在光效上达到了新的高度。作为符合EIA规范和ROHS标准的环保产品,H11-F312QLB/5M展现了QILSTE对绿色制造的承诺。其防潮等级达到Level......
  • SIL-PEG-SH,Silane-PEG-Thiols能与多种生物分子和材料形成稳定的共价键
    【试剂详情】英文名称Silane-PEG-SH,SIL-PEG-SH,Silane-PEG-Thiols,SIL-PEG-Thiols中文名称三乙氧基硅烷聚乙二醇巯基,三乙氧基硅烷PEG巯基外观性状由分子量决定,固体或者液体。分子量0.4k,0.6k,1k,2k,3.4k,5k,10k(可定制)溶解性溶于水,溶于DMF、DMSO等部分有机溶液规......
  • SIL-PEG-AA,Silane-PEG-Acetic Acid可制备高分子聚合物和有机硅材料
    【试剂详情】英文名称Silane-PEG-AA,SIL-PEG-AA,Silane-PEG-AceticAcid,SIL-PEG-AceticAcid中文名称三乙氧基硅烷聚乙二醇乙酸,三乙氧基硅烷PEG乙酸外观性状由分子量决定,固体或者液体。分子量0.4k,0.6k,1k,2k,3.4k,5k,10k(可定制)溶解性溶于水,溶于DMF、DMSO等部分有......
  • Silane-PEG-Hydroxyls,SIL-PEG-OH可减少蛋白质和肽的免疫原性
    【试剂详情】英文名称Silane-PEG-OH,Silane-PEG-Hydroxyls,SIL-PEG-OH,SIL-PEG-Hydroxyls中文名称三乙氧基硅烷聚乙二醇羟基,三乙氧基硅烷PEG羟基外观性状由分子量决定,固体或者液体。分子量0.4k,0.6k,1k,2k,3.4k,5k,10k(可定制)溶解性溶于水,溶于DMF、DMSO等部分有机......
  • Beyond Compare软件最新版下载及详细安装教程
    ​BeyondCompare是一款不可多得的专业级的文件夹和文件对比工具,使用它可以很方便地对比出两个文件夹或者文件的不同之处,相差的每一个字节用颜色加以表示,查看方便,支持多种规则对比,是程序工程师以及上班族必备的有效辅助工具。安装包获取地址:beyondcomparewin版:​​......
  • BarTender软件下载附加详细安装教程
    BarTender是美国海鸥科技推出的一款优秀的条码打印软件,应用于WINDOWS95、98、NT、XP、2000、2003和3.1版本,产品支持广泛的条形码码制和条形码打印机,不但支持条形码打印机而且支持激光打印机,还为世界知名品牌条形码打印机开发了增强驱动。​安装包获取......
  • NI SCXI-1000 数据采集和控制框架
    SCXI-1000特点:模块化设计:该框架采用模块化设计,可以根据实际需求选择不同的模块进行组合,以满足各种数字量控制系统的需求。高可靠性:在设计和制造过程中采用了高品质的材料和工艺,保证了其能够在恶劣的环境条件下稳定运行。多通道支持:支持多个数字量输入/输出通道,可以同时处理......
  • 基于数据挖掘的虚假评论识别方法研究(论文模版参考)
    第一章绪论1.1研究背景和意义随着互联网和社交媒体的快速发展,人们越来越倾向于在网络上表达自己的观点和评价。虚假评论作为网络评论的一种,对消费者、商家以及整个市场都带来了很大的影响。虚假评论不仅误导了消费者的购买决策,损害了商家的信誉,还可能导致市场竞争的扭曲......
  • 基于全数字中频架构的低采样率频谱分析系统研究与实现(论文)
    目录第一章绪论III1.1课题来源及意义III1.2研究现状及发展态势III1.3课题研究内容III1.4论文特色IV第二章整体仿真与介绍52.1系统整体架构52.2系统整体模拟仿真52.3硬件开发平台选择与介绍6第三章数字下变频93.1信号下变频架构对比与选择93.2信......