一、类OGRE实现
在OGRE中是这样实现的,代码如下:
templateclass Singleton { private: Singleton(const Singleton &); Singleton& operator=(const 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*)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; } };
- 在创建之前唯一实例的指针为NULL,必须显式地构造一个实例,因此构造函数必须为public。创建之后有了这个实例,再调用构造函数的话会assert失败。
- 因为是在栈上分配的空间,所有不用手动删除。
- 明明是singleton,却必须把构造函数设为public太让人不能接受了。
- 但是它有它的好处,它可以做为更高级的manager类的成员。比如OGRE里面,Root对象包含了多个Singleton成员,便于管理。
二、 内部类来实现
templateclass singleton { private: singleton(const singleton& anothor); singleton& operator = (const singleton &); protected: singleton() { } virtual ~singleton(){ } static T* instance; public: static T* getsingletonptr() { if (instance == NULL) { instance = new T(); static deleter mdeleter; } return instance; } static T& getsingleton() { return *getsingletonptr(); } private: class deleter { public: ~deleter() { delete instance; } }; }; template T* singleton ::instance = NULL;
- 定义了一个内部类,再定义一个此类的对象作为singleton的静态成员。由于类的成员变量存放在全局变量区,由系统自动地构造和析构。于是利用这一特性,在该静态成员析构时顺便析构掉singleton的唯一实例(此时的唯一实例在堆上创建)。
- 派生自该该模板的子类class Devided : public singleton<Devided>需这样定义(其他方式也如此)。子类的构造函数可以是private,这是一大好处。
- 由于子类的构造函数是private,在singleton里面需要调用子类的构造函数,于是可以将singleton<Devided>设为Devided的友元类。
三、 静态局部唯一实例
templateclass singleton { private: singleton(const singleton& anothor); singleton& operator = (const singleton &); protected: singleton() { } virtual ~singleton() { } public: static T* getsingleton() { static T instance; //this is important. return &instance; } };
- 简单
- 简单
- 还是简单