#ifndef _SINGLETON_H__
#define _SINGLETON_H__
// Added by Steve Streeting for Ogre
#include "OgrePrerequisites.h"
#include "OgreHeaderPrefix.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 {
/** \addtogroup Core
* @{
*/
/** \addtogroup General
* @{
*/
// End SJS additions
/** Template class for creating single-instance global classes.
*/
template <typename T> class Singleton
{
private:
/** \brief Explicit private copy constructor. This is a forbidden operation.*/
Singleton(const Singleton<T> &);
/** \brief Private operator= . This is a forbidden operation. */
Singleton& operator=(const Singleton<T> &);
protected:
static T* msSingleton;
public:
Singleton( void )
{
assert( !msSingleton );
#if defined( _MSC_VER ) && _MSC_VER < 1200
int offset = (int)(T*)1 - (int)(Singleton <T>*)(T*)1;
msSingleton = (T*)((int)this + offset);
#else
msSingleton = static_cast< T* >( this );
#endif
}
~Singleton( void )
{ assert( msSingleton ); msSingleton = 0; }
static T& getSingleton( void )
{ assert( msSingleton ); return ( *msSingleton ); }
static T* getSingletonPtr( void )
{ return msSingleton; }
};
/** @} */
/** @} */
}
#if defined ( OGRE_GCC_VISIBILITY )
# pragma GCC visibility pop
#endif
#include "OgreHeaderSuffix.h"
#endif
Singleton( void )
{
assert( !msSingleton );
#if defined( _MSC_VER ) && _MSC_VER < 1200
int offset = (int)(T*)1 - (int)(Singleton <T>*)(T*)1;
msSingleton = (T*)((int)this + offset);
#else
msSingleton = static_cast< T* >( this );
#endif
}
这个构造函数,折腾了一上午,最后问人明白了。
_MSC_VER是VS的版本宏 1700是VS2012,1600是2010,1200就是5.0啦。
当时还没有static_cast来方便的实现从基类到子类的转换,所以,需要计算偏移量。
然后,将Singleton类的指针转换为Singleton的子类指针然后保存到msSingleton里。
注:之所以需要转换为子类,是因为,Singleton只提供了,单件的功能,并没有提供其他的功能。