人工智慧——Singleton模式
上次在狀態模式中的設計有一個嚴重的問題,就是如下:
void CTroll::ChageState(CState* pNewState)
{
delete m_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對象才被構造出來。)比如以下代碼:
class CState_Runaway:public CState
{
private: //構造函數,拷貝構造和賦值重載全都私有化
CState_Runaway(){};
CState_Runaway(const CState_Runaway&);
CState_Runaway& operator=(const CState_Runaway&);
void Run(){cout<<"I will run away!"<<endl;}
public:
void execute(CTroll* troll);
static CState_Runaway* GetInstance(); //靜態實例化函數
};
靜態實例化函數實現如下:
CState_Runaway* CState_Runaway::GetInstance()
{
static CState_Runaway runaway; //local static對象
return &runaway;
}
靜態實例化函數調用:
void CState_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模式後,每種狀態實例只有一個,全局存在,所以以後智能體不管切換多少次狀態都不需要再重新申請內存,大大減少運行時間。
推薦閱讀:
※駕馭AI:好的數據集是成功的一半
※淺談強人工智慧的瓶頸和可能的努力方向
※一位00後由國內外教育經歷所引發的思考
※振奮,嗨翻 | AWS re:Invent 2017 第二天回顧
※百年奧運是一部科技史,智能奧運在平昌冬奧會浮出水面
TAG:人工智慧 |