3、Ogre中的单例类实现在Ogresinglton.h
Code
#ifndef _SINGLETON_H__
#define _SINGLETON_H__
// Added by Steve Streeting for Ogre
#include "OgrePrerequisites.h"
#if OGRE_COMPILER == OGRE_COMPILER_MSVC
// Turn off warnings generated by this singleton implementation
# pragma warning (disable : 4311)
# pragma warning (disable : 4312)
#endif
#if defined ( OGRE_GCC_VISIBILITY )
# pragma GCC visibility push(default)
#endif
namespace Ogre {
// End SJS additions
/** Template class for creating single-instance global classes.
*/
template <typename T> class Singleton
{
protected:
static T* ms_Singleton;
public:
Singleton( void )
{
assert( !ms_Singleton );
#if defined( _MSC_VER ) && _MSC_VER < 1200
int offset = (int)(T*)1 - (int)(Singleton <T>*)(T*)1;
ms_Singleton = (T*)((int)this + offset);
#else
ms_Singleton = static_cast< T* >( this );
#endif
}
~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; }
};
}
#if defined ( OGRE_GCC_VISIBILITY )
# pragma GCC visibility pop
#endif
#endif
需要使用 Singleton 的类,只要继承它即可:
class MyClass : public Singleton<MyClass>{// ..}
但在OGRE 的源码中我们可以发现,从Singleton 继承的类都Override 了Singleton
的成员getSingleton 和 getSingletonPtr。OGRE 中是这样解释的:
Singleton的实现都在 OgreSingleton.h文件中,这意味着任何包含OgreSingleton.h 头文件的文件编译后都有 Singleton 的一份实现,这符合模板机制。但
是从别的dll 中使用基于Singleton 的类时,就会产生连接错误。子类Override 一下,把实现放在.cpp 中,就会避免该问题。
下面是我的Ogre的singleton测试代码:
Code
#include "stdafx.h"
#include <assert.h>
#include <iostream>
using namespace std;
template <typename T> class Singleton
{
protected:
static T* ms_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; }
};
class MyRoot : public Singleton<MyRoot>
{
public:
static MyRoot& getSingleton(void);
static MyRoot* getSingletonPtr(void);
int data;
MyRoot():data(0) {};
MyRoot(int t):data(t) {};
~MyRoot() { };
void showMsg() { cout<<"test"<<endl;}
};
template<> MyRoot* Singleton<MyRoot>::ms_Singleton = 0;
MyRoot* MyRoot::getSingletonPtr(void)
{
return ms_Singleton;
}
MyRoot& MyRoot::getSingleton(void)
{
assert( ms_Singleton ); return ( *ms_Singleton );
}
int _tmain(int argc, _TCHAR* argv[])
{
MyRoot root1;
//如果加上这句就会出错,root1调用构造函数时候,会调用singleton构造函数,定义静态ms_Singleton
//定义root2时候,ms_Singleton已经定义,所以会弹出异常
//MyRoot root2;
root1.showMsg();
MyRoot::getSingleton().showMsg();
return 0;
}