zoukankan      html  css  js  c++  java
  • singleton模式的三种模板实现

     一、类OGRE实现

    在OGRE中是这样实现的,代码如下:

    template <typename T> class Singleton

    {

    private:

    Singleton(const Singleton<T> &);

    Singleton& operator=(const Singleton<T> &);



    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; }

    };
    1. 在创建之前唯一实例的指针为NULL,必须显式地构造一个实例,因此构造函数必须为public。创建之后有了这个实例,再调用构造函数的话会assert失败。
    2. 因为是在栈上分配的空间,所有不用手动删除。
    3. 明明是singleton,却必须把构造函数设为public太让人不能接受了。
    4. 但是它有它的好处,它可以做为更高级的manager类的成员。比如OGRE里面,Root对象包含了多个Singleton成员,便于管理。

    二、 内部类来实现

    template<typename T>

    class singleton

    {

    private:

    singleton(const singleton& anothor);

    singleton& operator = (const singleton<T>&);

    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<typename T>

    T* singleton<T>::instance = NULL;

     

    1. 定义了一个内部类,再定义一个此类的对象作为singleton的静态成员。由于类的成员变量存放在全局变量区,由系统自动地构造和析构。于是利用这一特性,在该静态成员析构时顺便析构掉singleton的唯一实例(此时的唯一实例在堆上创建)。
    2. 派生自该该模板的子类class Devided : public singleton<Devided>需这样定义(其他方式也如此)。子类的构造函数可以是private,这是一大好处。
    3. 由于子类的构造函数是private,在singleton里面需要调用子类的构造函数,于是可以将singleton<Devided>设为Devided的友元类。

    三、 静态局部唯一实例

    template<typename T>

    class singleton

    {

    private:

    singleton(const singleton& anothor);

    singleton& operator = (const singleton<T>&);



    protected:

    singleton() { }

    virtual ~singleton() { }



    public:

    static T* getsingleton()

    {

    static T instance; //this is important.

    return &instance;

    }

    };
    1. 简单
    2. 简单
    3. 还是简单
  • 相关阅读:
    iOS13 present VC方法
    青囊奥语
    三元九运的排盘
    三元九运 笔记
    青囊经
    金钱卦起卦
    易经中九二六三是什么意思
    用神
    六爻预测中的世爻,应爻分别代表什么
    div2-1519-D-Maximum Sum of Products-dp
  • 原文地址:https://www.cnblogs.com/jianqifeihong/p/2233086.html
Copyright © 2011-2022 走看看