Singleton模式的C++实现研究

2012/6/13 11:47:00  请友读忠(更多)  E界MRP开发下载网  473阅

Singleton(单件)模式是一种很常用的设计模式。《Design Patterns》对它作的定义为:Ensure a class only has one instance, * provide a global point of access to it. 也就是说单件类在整个应用程序的生命周期中只能有一个实例存在,使用者通过一个全局的访问点来访问该实例。这是Singleton的两个最基本的特征,也是在实现的时候首先应该考虑的。Singleton的应用很广,它可以典型的被用来表示那些本性上具有唯一特性的系统组件,如数据库访问组件等。这一点在《Design Patterns》上有详细说明,在此就不细说了。 实现Singleton有很多途径,但都离不开两条最基本的原则。首先,要使得Singleton只有一个全局唯一的实例,我们通常的做法是将它的构造函数和拷贝构造函数私有化。再者,Singleton的全局唯一实例通常是一个static变量,这一点利用了语言的内在优势。本文给出的几种实现都比较简单,容易理解。在通常的情况下,它们足以满足要求。但缺点也是不可避免,以下我们逐一分析。 一、基于模板函数的实现 先看实现代码: class MySingleton1 { private: MySingleton1(){ cout friend T& GetInstanceRef(); public: “MySingleton1(){ cout T& GetInstanceRef() //返回全局唯一对象的一个引用 { static T _instance; return _instance; } template T* GetInstancePtr() //返回全局唯一对象的指针 { return &GetInstanceRef(); } 上面的代码中,MySingleton1是需要单实例化的类。下面的模板函数template T& GetInstanceRef()返回该类的唯一实例(静态变量_instance)的一个引用,另一个模板函数调用它返回该实例的指针。我们可以注意到以下几点: 1. MySingleton1的构造函数私有,防止了程序员随意构造它的实例。 2. 同样,拷贝构造函数MySingleton1(const MySingleton1&)也被声明为私有。 3. 全局的模板函数template T& GetInstanceRef()是MySingleton1的友元。因为MySingleton1的构造函数已经声明为私有,为了让GetInstanceRef能顺利的构造静态变量_instance,我们不得不将它声明为MySingleton1的友元函数。 这样,我们的类MySingleton1就具有了Singleton特性了,而全局访问点就是两个模板函数。测试代码如下: MySingleton1* myobj1; myobj1 = GetInstancePtr(); myobj1->DoSomething(); GetInstanceRef().DoSomething(); 下面我们分析这种实现的缺点。由于模板函数GetInstanceRef被特化后要访问MySingleton1,它的声明必须在类(MySingleton1)声明之后(区分声明与实现),这与我们通常的使用方式不合。虽然它在其它方面表现的比较良好,但就这一个缺点已经使我不会再想使用它了。来看第二种可以实际使用的实现。 二、基于模板类的实现 这种实现的基本思路是,做一个类让它来负责提供Singleton对象的生成与访问。由于它要构造Singleton对象,所以让它成为一个友元是理所当然的。下面看看实现代码: template 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; \
分享至:
good 34

发表评论

文明评论,重在参与

暂无评论!
返回上级 返回首页
首页合作客服留言QQ群简版
E界,引领视界
mrpej.com @CopyRight