上次在状态模式中的设计有一个严重的问题,就是如下:

voidCTroll::ChageState(CState* pNewState)

{

       deletem_pCurrentState;

       m_pCurrentState=pNewState;

       Update();

}

在状态切换中不断有内存申请、删除的操作,如果智能体状态切换频繁,会非常消耗时间。要解决这个问题,就要用到Singleton模式。

Singleton模式有多种实现方法,其核心就是把类构造函数私有化,使得外部不能实例化该类。然后在类内部用一个全局的静态函数来完成类的实例化,用一个静态变量保存唯一实例地址。但为了解决线程安全问题,Scott Meyers在《Effective C++》(Item 04)中提出一种更优雅的单例模式实现,使用local static对象(C++中的static对象是指存储区不属于stack和heap、"寿命"从被构造出来直至程序结束为止的对象。其中,函数内的static对象称为local static 对象,而其它static对象称为non-local static对象。对于local static对象,在其所属的函数被调用之前,该对象并不存在,即只有在第一次调用对应函数时,local static对象才被构造出来。)比如以下代码:

classCState_Runaway:publicCState

{

private:     //构造函数,拷贝构造和赋值重载全都私有化

       CState_Runaway(){};

       CState_Runaway(constCState_Runaway&);

       CState_Runaway&operator=(constCState_Runaway&);

 

       voidRun(){cout<<"I will run away!"<<endl;}

public:   

       voidexecute(CTroll* troll);

       staticCState_Runaway*GetInstance();  //静态实例化函数

};

静态实例化函数实现如下:

CState_Runaway*CState_Runaway::GetInstance()

{

       staticCState_Runaway runaway;    //local static对象

       return&runaway;

}

静态实例化函数调用:

voidCState_Runaway::execute(CTroll* troll)

{

       if(troll->GetSafe())

       {

              troll->ChageState(CState_Sleep::Getinstance());

/*静态实例化函数第一次调用时local static对象才被执行,实例化成功后,以后再调用就不会执行了。*/

       }

       else

       {

              Run();

       }

}

最后别忘了把CTroll的析构函数删除状态指针的语句去掉。

CTroll::~CTroll(void)

{

       //delete m_pCurrentState;   //由于是静态对象,所以不能用delete删除。delete只能删除heap里的对象,而静态对象在全局区里,随程序结束自动销毁。

}

用singleton模式后,每种状态实例只有一个,全局存在,所以以后智能体不管切换多少次状态都不需要再重新申请内存,大大减少运行时间。

人工智能——Singleton模式的更多相关文章

  1. Qt 中使用Singleton模式需小心

    在qt中,使用Singleton模式时一定要小心.因为Singleton模式中使用的是静态对象,静态对象是直到程序结束才被释放的,然而,一旦把该静态对象纳入了Qt的父子对象体系,就会导致不明确的行为. ...

  2. 剑指Offer面试题:1.实现Singleton模式

    说来惭愧,自己在毕业之前就该好好看看<剑指Offer>这本书的,但是各种原因就是没看,也因此错过了很多机会,后悔莫及.但是后悔是没用的,现在趁还有余力,把这本书好好看一遍,并通过C#通通实 ...

  3. C++ Singleton模式

    地址:http://www.cppblog.com/dyj057/archive/2005/09/20/346.html Singleton模式是常用的设计模式之一,但是要实现一个真正实用的设计模式却 ...

  4. Singleton模式——对象创建型模式

    Singleton模式即为单例模式/单件模式. (一)意图--保证一个类仅有一个实例,并提供一个访问它的全局访问点. 如一台计算机可以有多个端口,但是应该统一管理这些端口,避免访问冲突.--选择Sin ...

  5. Singleton模式和Mono-State模式

    类和实例 对于大多数的类,都可以创建多个实例.在需要和不需要时,创建和删除这些实例.该过程会伴随着内存的分配和归还. 同时,有一些类,应该仅有一个实例.该实例在程序启动/结束时被创建和删除. root ...

  6. 转:Singleton模式

    C++完美实现Singleton模式  转自:http://www.cppblog.com/dyj057/archive/2005/09/20/346.html boost库的Singleton的实现 ...

  7. Singleton模式

    Singleton模式的特点: 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 定义一个Instance操作,允许客户访问它的唯一实例.Instance是一个类操作(C++中的一个静态成员函数 ...

  8. Objective-C的singleton模式

    最近因为在ios应用开发中,考虑到一些公共方法的封装使用,就决定使用单例模式的写法了..不知道,Object-c中的单例模式的写法是否和java中的写法是否有所区别?于是阿堂从网上一搜,发现“ Obj ...

  9. js中singleton模式解析及运用

    singleton模式,又名单例模式.顾名思义,就是只能实例化一次的类(javascript中没有真正的类,我们通常用函数来模拟类,习惯称之为"伪类").具体地说,singleto ...

随机推荐

  1. Java 8 新特性-菜鸟教程 (4) -Java 8 默认方法

    Java 8 默认方法 Java 8 新增了接口的默认方法. 简单说,默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法. 我们只需在方法名前面加个default关键字即可实现默认方法. 为 ...

  2. 了解MySQL联表查询中的驱动表,优化查询,以小表驱动大表

    一.为什么要用小表驱动大表 1.驱动表的定义 当进行多表连接查询时, [驱动表] 的定义为: 1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表] 2)未指定联接条件时,行数少的表为[驱动表 ...

  3. 记一次pm2的踩坑

    1.问题: 公司采用了自动发布平台,最近突然发现一个问题,上线完成后服务是能正常访问的,但是有一个节点访问的时候每两次中总是有一次404,通过nginx的access日志分析发现第一次正常访问有一次g ...

  4. Docker 入门 之基本命令

    3 Docker 入门 首先确保docker 已成功安装在Linux 或windows 系统中 我们可以使用 docker info 查看docker是否成功安装和正常运行 运行我们第一个docker ...

  5. JS继承实现的几种方式

    //继承的几种实现: //解决方案1.通过原型继承 function Parent1(){ this.name = 'Parent1'; } function Child1(){} Child1.pr ...

  6. C# Thread.Abort方法真的让线程停止了吗?

    大家都知道在C#里面,我们可以使用 Thread.Start方法来启动一个线程,当我们想停止执行的线程时可以使用Thread.Abort方法来强制停止正在执行的线程,但是请注意,你确定调用了Threa ...

  7. SQl语句查询性能优化

    [摘要]本文从DBMS的查询优化器对SQL查询语句进行性能优化的角度出发,结合数据库理论,从查询表达式及其多种查询条件组合对数据库查询性能优化进行分析,总结出多种提高数据库查询性能优化策略,介绍索引的 ...

  8. oracle逐步学习总结之约束(基础五)

    原创作品,转自请在文章明显位置注明出处:https://www.cnblogs.com/sunshine5683/p/10167717.html oracle中的约束主要有非空约束(not null) ...

  9. ArrayList源码解读(jdk1.8)

    概要 上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具体实现类进行讲解:首先,讲解List,而List中ArrayList又最为常用.因此,本章我们讲解Arra ...

  10. 记一次Full GC问题的排查

    今天看到监控平台显示项目的Full GC次数过多,查看了一下监控曲线,如下图,发现发生的时间点基本上都是在上午十点之后,到下午五点. 分析:考虑到业务形态,开始初步怀疑是访问人数增多引起的虚拟机内存不 ...