Singleton实现

Singleton实现 转自88 c/c++

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                            方案A
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
该方案为Design Patterns所列举的最简单的一种实现方法(以下的代码
是按照我自己的编码习惯写的,但是语意上和DP里的实现没有区别):
---- Declaration A ----
class Singleton {
public:
    static Singleton * instance();
protected:
    Singleton();
private:
    static Singleton * me;
};
---- Implementation A ----
Singleton * Singleton::me = 0;
Singleton * Singleton::instance() {
    if( me == 0 )
        me = new Singleton();
    return me;
}
简述:  通过对默认构造函数的保护基本上实现了Singleton模式的初衷,
        利用一个静态指针me来指向唯一的一个Singleton实例,同时使用
        lazy initialization(中文版的DP里翻译成惰性初始化,感觉很
        别扭)来延迟了Singleton对象的内存分配和构造。
使用:  将需要以Singleton模式实现的类由Singleton为基类派生即可。当然
        那样的话要将Singleton的析构函数写成virtual。
缺陷:  ·  只将默认构造函数作为保护成员,却没有保护拷贝构造函数和
            operator=(),造成了漏洞,例如如下代码:
            Singleton * pFirst = Singleton::instance();
            Singleton second( * pFirst );
            Singleton third = second;
            便创建了三个Singleton对象,使得Singleton模式被破坏。
        ·  没有保护析构函数,因此如果对Singleton::instance()所返回
            的Singleton指针进行delete,或者通过指针显式调用析构函数,
            则静态指针me将成为野指针,并且由于没有被清零,再次调用
            Singleton::instance()将成为危险的动作,并可能造成复杂的
            运行期错误。
补充:  ·  将拷贝构造和operator=()也列为protected。
        ·  如果Singleton对象构造后不允许被析构,则将析构函数列位
            protected并定义为virtual;如果允许Singleton对象被析构和
            再创建,则应该在析构函数中对静态指针me进行清零。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                            方案B
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
该方案实际上只是方案A的一个简单变种:
---- Declaration B ----
class Singleton {
public:
    static Singleton& instance( void ) {
        static Singleton me;
        return me;
    }
protected:
    Singleton( void ) {
    }
    Singleton( const Singleton& ) {
    }
    virtual ~Singleton( void ) {
    }
    const Singleton& operator=( const Singleton& ) {
    }
private:
};
简述:  该方案补充了方案A的缺陷,同时利用局部静态变量,而不是作为
        成员变量的静态指针来维系instance()和Singleton的唯一实例之间
        的关系,从而简化了类结构,免除了一个成员变量。并且由于在且
        仅在第一次调用instance()的时候,局部静态变量me才会被构造,
        该方案很自然地实现了lazy initialization。同时instance()函数
        的返回值由指针改为引用,防止了delete操作,当然由于析构函数
        被保护,即使返回值为指针,进行delete操作也会造成编译期错误。
        应该说除了下述的缺陷外,该方案的Singleton实现是比较完善的。
使用:  和方案A一样,将Singleton作为基类来使用。
缺陷:  由于是使用局部静态变量来实例化Singleton对象,虽然Singleton的
        唯一实例me是在第一次调用instance()的时候构造的,但是me的内存
        却是编译期确定下来的,不像方案A那样可以动态分配内存。
            由此直接导致的问题就是该方案不能像方案A(的补充改进版本)
        那样允许Singleton实例被析构并再次构造。因为instance()除了第一
        次被调用以外,就没有再次调用Singleton构造函数的机会了。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                            方案C
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
该方案的实现比较有趣,利用了模板和私有继承。事实上以下代码改编自
Boost库中的一个Singleton实作。我使用的Boost版本为1.32.0,原代码
文件位置为:
    boost_1_32_0/boost/thread/detail/singleton.hpp
---- Declaration C ----
template <class Type>
class Singleton : private Type {
public:
    static Type& instance( void );
private:
    Singleton();
    ~Singleton();
};
template <class Type>
inline Singleton<Type>::Singleton() {
    // ...
}
template <class Type>
inline Singleton<Type>::~Singleton() {
    // ...
template <class Type>
inline Type& Singleton<Type>::instance() {
    static Singleton<Type> me;
    return me;
}
简述:  该方案的优点是可以轻易地对已有的、并未按照Singleton模式
        封装的类实现Singleton模式。容易应用于现存的代码中。并且
        不需要单独为所有需要实现Singleton模式的类建立一个以
        Singleton类为基类的继承体系。
            如同方案B,该方案也是利用局部静态变量的方法来存储类
        的唯一实例。注意返回值类型为模板类型参数Type的引用,但是
        instance()方法中实际返回的是一个Singleton<Type>的引用。
        在代码中可以看出,Singleton<Type>是Type类型的一个私有继
        承的子类,所以返回一个Singleton<Type>引用没有问题。这样
        做可以保持Singleton对象的特性。
            事实上,方案B就是对Boost库中的singleton和noncopyable
        的借鉴结果。
使用:  需要一个类的Singleton实例时,调用Singleton<Type>::instance()
        即可。
缺陷:  基于同方案二一样的原因,该方案也不允许已创建的Singleton实例
        被析构并再次构造。不过一般来说这个限制也无关紧要,Boost库中
        大量使用了这种Singleton模板。如果真的需要,就如同方案A一样,
        改用作为成员变量的静态指针来关联Singleton实例即可。

你可能感兴趣的:(Singleton实现)