人工智能——Singleton模式

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

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

上一篇:20145227鄢曼君《网络对抗》逆向及Bof基础


下一篇:MySQL的事务机制和锁(InnoDB引擎、MVCC多版本并发控制技术)