C++ 中的Singleton 类的实现
来源:互联网 发布:美女种田网络图片 编辑:程序博客网 时间:2024/05/16 01:23
ANSI C++ 中的 Singleton 实现说难不难,说容易也不容易,很多人写 ANSI C++ 的 Singleton class 都有错误。这篇文章讨论怎样在 ANSI c++ 中写 Singleton class, 希望对大家有帮助。
《设计模式》中把 Singleton 写成返回指针:
- class Singleton{
- public:
- static Singleton* Instance();
- protected:
- Singleton();
- private:
- static Singleton* _instance;
- };
相应的实现 cpp 文件是
- Singleton* Singleton::_instance;
- Singleton* Singleton::Instance(){
- if( _instance == 0){
- _instance = new Singleton;
- };
- return _instance;
- }
将构造函数设计成 protected 的目的是防止在 class 外面 new ,有人可能会设计成 private ,如果考虑到有可能会继承这个类的话,还是将构造函数设计成 protected 比较好,还需要加一个 virtual 析构函数。为了防止别人复制 Singleton 对象:
- Singleton* pSingleton = Singleton::Instance();
- Singleton s1 = *pSingleton;
- Singleton s2 = *pSingleton;
- 需要将拷贝构造(copy constructor)函数变成 private。
但是这里存在的问题是,什么时候删除 Singleton 对象?按照 C++ 的一个基本原则,对象在哪里创建就在哪里销毁,这里还应该放一个 destroy 方法来删除 Singleton 对象。如果忘了删除就比较麻烦。Instance 函数还存在多线程同时访问的加锁问题。如果把 Instance 函数开始和结尾放上加锁和解锁,整个函数性能会下降很多。这不是一个好的设计。
有一个小小的改动,可以避免忘了删除 Singleton 对象带来内存泄露的问题。那就是用 std:auto_ptr 来包含 Singleton 对象,定义一个class static member auto_ptr 对象,在析构的静态 auto_ptr 变量的时候时候自动删除 Singleton 对象。为了不让用户 delete Singleton 对象,需要将析构函数由 public 变成 protected。以下是头文件 SingletonAutoPtr.h :
- #include <memory>
- using namespace std;
- class CSingletonAutoPtr
- {
- private:
- static auto_ptr<CSingletonAutoPtr> m_auto_ptr;
- static CSingletonAutoPtr* m_instance;
- protected:
- CSingletonAutoPtr();
- CSingletonAutoPtr(const CSingletonAutoPtr&);
- virtual ~CSingletonAutoPtr();
- //allow auto_ptr to delete, using protected ~CSingletonAutoPtr()
- friend class auto_ptr<CSingletonAutoPtr>;
- public:
- static CSingletonAutoPtr* GetInstance();
- void Test();
- };
- #include "SingletonAutoPtr.h"
- #include <iostream>
- //initial static member vars here
- CSingletonAutoPtr* CSingletonAutoPtr::m_instance = NULL;
- auto_ptr<CSingletonAutoPtr> CSingletonAutoPtr::m_auto_ptr;
- /////////////////////////////////////////
- // Construction/Destruction
- /////////////////////////////////////////
- CSingletonAutoPtr::CSingletonAutoPtr()
- {
- cout << "CSingletonAutoPtr::CSingletonAutoPtr()" << endl;
- //put single object into auto_ptr object
- m_auto_ptr = auto_ptr<CSingletonAutoPtr>(this);
- }
- CSingletonAutoPtr::~CSingletonAutoPtr()
- {
- cout << "CSingletonAutoPtr::~CSingletonAutoPtr()" << endl;
- }
- CSingletonAutoPtr* CSingletonAutoPtr::GetInstance()
- {
- //begin lock
- //....
- if(m_instance == NULL)
- m_instance = new CSingletonAutoPtr();
- //end lock
- //...
- return m_instance;
- }
- void CSingletonAutoPtr::Test()
- {
- cout << "CSingletonAutoPtr::Test()" << endl;
- }
- CSingletonAutoPtr* pSingleton = CSingletonAutoPtr::GetInstance();
- pSingleton->Test();
另外一个思路是,把 GetInstance 函数设计成 static member 可能更好,因为一般来说,Singleton 对象都不大,static member 虽然必须一直占用内存,问题不大。这里的析构函数必须设成 public 了。以下是头文件 SingleStaticObj.h
- class CSingletonStaticObj
- {
- private:
- static CSingletonStaticObj m_instance;
- protected:
- CSingletonStaticObj();
- CSingletonStaticObj(const CSingletonStaticObj&);
- public:
- virtual ~CSingletonStaticObj(); //must public
- static CSingletonStaticObj& GetInstance();
- void Test();
- };
- 对应的 SingleStaticObj.cpp 文件为:
- #include "SingletonStaticObj.h"
- #include <string>
- #include <iostream>
- using namespace std;
- CSingletonStaticObj CSingletonStaticObj::m_instance;
- CSingletonStaticObj::CSingletonStaticObj()
- {
- cout << "CSingletonStaticObj::CSingletonStaticObj()" << endl;
- }
- CSingletonStaticObj::~CSingletonStaticObj()
- {
- cout << "CSingletonStaticObj::~CSingletonStaticObj()" << endl;
- }
- CSingletonStaticObj& CSingletonStaticObj::GetInstance()
- {
- return m_instance;
- }
- void CSingletonStaticObj::Test()
- {
- cout << "CSingletonStaticObj::Test()" << endl;
- }
- CSingletonStaticObj& singleton = CSingletonAutoPtr::GetInstance();
- singleton.Test();
但是,并不是所有情况下面都适合用 static member singleton。比如说,GetInstance 需要动态决定返回不同的 instance 的时候,就不能用。举例来说,FileSystem::GetInstance, 在 windows 下面运行可能需要返回 new WinFileSystem, Linux/Unix 下面运行可能需要返回 new LinuxFileSystem,这个时候还是需要用上面的 auto_ptr 包含 singleton 指针的方法。
- C++ 中的Singleton 类的实现讨论
- C++ 中的singleton 类的实现讨论
- C++ 中的Singleton 类的实现讨论
- C++ 中的Singleton 类的实现
- C++ 中的Singleton 类的实现讨论
- cocoa 中的 Singleton 的实现
- c++--Singleton单例模式的实现
- objective-c中的Singleton单例模式的完整实现示例
- objective-c中的Singleton单例模式的完整实现示例
- objective-c中的Singleton单例模式的完整实现示例
- objective-c中的Singleton单例模式的完整实现示例
- objective-c中的Singleton单例模式的完整实现示例
- C++ 中的 Singleton 实现
- C++ 中的 Singleton 实现
- C#中的Singleton实现
- C++ 中的 Singleton 实现
- 实现严谨的singleton类
- 【C++】实现Singleton模式
- 学习...
- Oracle 中如何判断一个字符串是否为数字
- ArcEngine 渲染的使用
- 做校内app半年的经验分享
- DB2字段类型研究 --- SMALLINT (小整型)
- C++ 中的Singleton 类的实现
- 一个还不错的gridview 样式
- access数据库加密
- C#创建COM的实例
- SQL server成批注入的方法
- xslt中获取当前XML文件名
- 软件开发需求分析五个常见错误及应对措施
- Linux下SVN远程web密码修改
- asp.net2的menu页面转向后实现selectedstyle,treeview同理