2015-08-15 66 views
2

我正在製作遊戲引擎,我正在使用庫來執行各種任務。例如,我使用需要初始化的FreeType,獲取管理器,並且在我不使用它之後,我必須對它進行初始化。當然,它只能初始化一次,只能在初始化後才能初始化。單身經理類,更好的設計?

我想出什麼了(只是舉個例子,不是 「真正的」 代碼[但可能是有效的C++代碼):

class FreeTypeManager 
{ 
private: 
    FreeTypeManager() {} // Can't be instantiated 

    static bool initialized; 
    static TF_Module * module; // I know, I have to declare this in a separate .cpp file and I do 

public: 
    static void Initialize() 
    { 
     if (initialized) return; 

     initialized = true; 
     FT_Initialize(); 
     FT_CreateModule(module); 
    } 

    static void Deinitialize() 
    { 
     if (!initialized) return; 

     initialized = false; 
     FT_DestroyModule(module); 
     FT_Deinit(); 
    } 
}; 

而對於每一個管理者創建(FreeType的,AudioManager,EngineCore,DISPLAYMANAGER )它幾乎是一樣的:沒有實例,只是靜態的東西。我可以看到,這可能是一個糟糕的設計實踐,每次都要重寫這個框架。也許有更好的解決方案。

改用singleton代替它會好嗎?還是有適合我的問題的模式?

回答

2

如果你仍然想單身的做法(這一種有意義的管理型對象),那麼爲什麼不讓它適當單,並且有靜態get功能,如果需要的話,創建管理對象,並讓管理者(私有)構造函數處理初始化並處理析構函數中的初始化(雖然管理器類型的對象通常具有整個程序的生命週期,所以析構函數只會在程序退出時調用)。

喜歡的東西

class FreeTypeManager 
{ 
public: 
    static FreeTypeManager& get() 
    { 
     static FreeTypeManager manager; 
     return manager; 
    } 

    // Other public functions needed by the manager, to load fonts etc. 
    // Of course non-static 

    ~FreeTypeManager() 
    { 
     // Whatever cleanup is needed 
    } 

private: 
    FreeTypeManager() 
    { 
     // Whatever initialization is needed 
    } 

    // Whatever private functions and variables are needed 
}; 

如果你不想單身,並且只有靜態函數的類,你還不如用一個namespace代替。對於變量,將它們放入實現(源)文件中的匿名名稱空間中。或者對數據使用不透明的結構指針(pimpl成語的變體)。

+0

這就是我要做的。謝謝! –

0

還有另一種解決方案,它不完全是單例模式,但非常相關。

class FreeTypeManager 
{ 
public: 
    FreeTypeManager(); 
    ~FreeTypeManager(); 
}; 
class SomeOtherClass 
{ 
public: 
    SomeOtherClass(FreeTypeManager &m) : m(m) {} 
private: 
    FreeTypeManager &m; 
}; 
int main() { 
    FreeTypeManager m; 
    ... 
    SomeOtherClass c(m); 
} 

解決方案是保持它的普通C++類,但只是在main()的開始處實例化它。這將初始化/破壞移動到一個不同的地方。您需要將引用傳遞給每個想通過構造函數參數使用FreeTypeManager的類。

請注意,使用main()而不是其他函數很重要;否則你會得到範圍問題,需要一些思考如何處理..

+0

這就像我最終做的一樣。我做單身人士,但我有一個控制器類,其中我存儲的實例,以方便訪問。謝謝你的提示! –