2015-08-15 69 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

这就像我最终做的一样。我做单身人士,但我有一个控制器类,其中我存储的实例,以方便访问。谢谢你的提示! –