当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++基础入门教程

Singleton模式的C++实现研究

        Singleton(单件)模式是一种很常用的设计模式。《Design Patterns》对它作的定义为:Ensure a class only has one instance, and provide a global point of access to it. 也就是说单件类在整个应用程序的生命周期中只能有一个实例存在,使用者通过一个全局的访问点来访问该实例。这是Singleton的两个最基本的特征,也是在实现的时候首先应该考虑的。Singleton的应用很广,它可以典型的被用来表示那些本性上具有唯一特性的系统组件,如数据库访问组件等。这一点在《Design Patterns》上有详细说明,在此就不细说了。

    实现Singleton有很多途径,但都离不开两条最基本的原则。首先,要使得Singleton只有一个全局唯一的实例,我们通常的做法是将它的构造函数和拷贝构造函数私有化。再者,Singleton的全局唯一实例通常是一个static变量,这一点利用了语言的内在优势。本文给出的几种实现都比较简单,容易理解。在通常的情况下,它们足以满足要求。但缺点也是不可避免,以下我们逐一分析。

 

    一、基于模板函数的实现

 

    先看实现代码:

    class MySingleton1

    {

    private:

        MySingleton1(){ cout << _T("Construct MySingleton1") << endl; }

        MySingleton1(const MySingleton1&){} //拷贝构造函数

    MySingleton1 & operator =(const MySingleton1&){} //赋值函数

        template <typename T>

        friend T& GetInstanceRef();

 

    public:

        ~MySingleton1(){ cout << _T("Destroy MySingleton1") << endl; }

 

    public:

        void DoSomething(){ cout << _T("Do something here in MySingleton1") << endl; }

    };

    template <typename T>

    T& GetInstanceRef() //返回全局唯一对象的一个引用

    {

        static T _instance;

        return _instance;

    }

    template <typename T>

    T* GetInstancePtr() //返回全局唯一对象的指针

    {

        return &GetInstanceRef<T>();

    }

    上面的代码中,MySingleton1是需要单实例化的类。下面的模板函数template <typename T> T& GetInstanceRef()返回该类的唯一实例(静态变量_instance)的一个引用,另一个模板函数调用它返回该实例的指针。我们可以注意到以下几点:

    1.    MySingleton1的构造函数私有,防止了程序员随意构造它的实例。

    2.    同样,拷贝构造函数MySingleton1(const MySingleton1&)也被声明为私有。

    3.    全局的模板函数template <typename T> T& GetInstanceRef()是MySingleton1的友元。因为MySingleton1的构造函数已经声明为私有,为了让GetInstanceRef能顺利的构造静态变量_instance,我们不得不将它声明为MySingleton1的友元函数。

 

    这样,我们的类MySingleton1就具有了Singleton特性了,而全局访问点就是两个模板函数。测试代码如下:

    MySingleton1* myobj1;

    myobj1 = GetInstancePtr<MySingleton1>();

    myobj1->DoSomething();

    GetInstanceRef<MySingleton1>().DoSomething();

        下面我们分析这种实现的缺点。由于模板函数GetInstanceRef被特化后要访问MySingleton1,它的声明必须在类(MySingleton1)声明之后(区分声明与实现),这与我们通常的使用方式不合。虽然它在其它方面表现的比较良好,但就这一个缺点已经使我不会再想使用它了。来看第二种可以实际使用的实现。

 

    二、基于模板类的实现

 

        这种实现的基本思路是,做一个类让它来负责提供Singleton对象的生成与访问。由于它要构造Singleton对象,所以让它成为一个友元是理所当然的。下面看看实现代码:

    template <typename T>

    class SingletonWraper

    {

    public:

    static T& GetInstanceRef()

    {

         static T _instance;

         return _instance;

    }

    static const T& GetInstanceConst()

    {

         return GetInstanceRef();

    }

    static T* GetInstancePtr()

    {

         return &GetInstanceRef();

    }

    };

    #define DEFINE_SINGLETON(ClassName); \

    public: \

    friend class SingletonWraper<ClassName>; \

 

共3页 首页 上一页 1 2 3 下一页 尾页 跳转到
相关内容
赞助商链接