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)

 

你可能感兴趣的:(设计模式,框架,manager,null,Class,dll)