Ogre的設計模式分析之-單件模式

小弟從來不盲目崇拜設計模式,項目中也切忌濫用設計模式的,但是有些作用十分不錯的設計模式還是應該運用的,Ogre在這方面就十分不錯,設計模式篩選的十分得當,代碼也十分優雅,對我影響很大,以至於我現在的代碼風格完全改變爲Ogre式的風格。

 

由於要設計整個客戶端的框架,所以靈活運用Ogre的一些設計模式對項目的幫助也是很大的。

先從單件入手吧,

爲什麼需要singleton,因爲每個相對獨立的模塊都應該有一個總類來管理,這個總類應該是唯一的,而且最好是靜態的,這樣在其他類中調用就十分方便。

 

唯一和靜態,這2個需求我們可以通過這樣實現

class Manager
{
public:
 Manager(void) { smSingelton = this; }
 static Manager* getSingletonPtr(void) { return smSingelton; }
 static Manager& getSingleton(void) { assert(smSingelton); return *smSingelton; }
protected:
 static Manager* smSingelton;
};

Manager* Manager::smSingelton = NULL;

 

但是如果有很模塊,需要很多個單件的管理器,最好就應該用模板來管理,Ogre就是類似這樣實現的

template <typename T> class Singleton
{

public:
    Singleton( void )
    {
        assert( !ms_Singleton );
        ms_Singleton = static_cast<T*>(this);
    }
   ~Singleton( void )
        {  assert( ms_Singleton );  ms_Singleton = 0;  }
    static T& getSingleton( void )
        {  assert( ms_Singleton );  return ( *ms_Singleton );  }
    static T* getSingletonPtr( void )
        {  return ( ms_Singleton );  }

protected:
    static T* ms_Singleton;
};

 

然後要用的時候只需要繼承這個單件模板類,重寫getSingleton函數:

class WindowManager : public Singleton <WindowManager>

{

 

// 重寫

    static  WindowManager* MaterialManager::getSingletonPtr(void)
    {
        return ms_Singleton;
    }
    static  WindowManager& MaterialManager::getSingleton(void)
    {
        assert( ms_Singleton );  return ( *ms_Singleton );
    }

}

 

 

 

然後在頭文件初始化靜態變量ms_Singleton;

template<> WindowManager* Singleton<WindowManager>::ms_Singleton = NULL;

 

---------------------------------------------------------------------------------------------------------------------------

上面的用法很簡單,但是如果你在外部用Ogre的單件模板類可能會遇到一個問題,就是dll導出模板類的問題

 

因爲Ogre是dll庫,dll動態庫是不能導出模板類的,應該模板是編譯時候決定類型的,但是dll是可以導出實例的模板類的,

改一下重寫的代碼,直接調用基類的函數:

class WindowManager : public Singleton <WindowManager>

{

 

// 重寫

static  WindowManager& WindowManager::getSingleton(void)
{
 return Singleton<WindowManager>::getSingleton();
}


static  WindowManager* WindowManager::getSingletonPtr(void)
{
 return Singleton<WindowManager>::getSingletonPtr();
}

}

 

最後,細節問題,到底我們該調用getSingleton還是getSingletonPtr

答案就是getSingleton更好,因爲getSingleton獲得引用必須是有斷言的安全校驗的,getSingletonPtr是沒有

 

注:上面的代碼都沒有添加dll的__declspec(dllexport)

 

發佈了67 篇原創文章 · 獲贊 68 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章