WEB开发网
开发学院软件开发C++ C++中的Singleton类的实现 阅读

C++中的Singleton类的实现

 2008-03-08 22:01:10 来源:WEB开发网   
核心提示:《设计模式》中把 Singleton 写成返回指针: class Singleton{public:static Singleton* Instance();PRotected:Singleton();private:static Singleton* _instance;};相应的实现 cpp 文件是:Singlet
《设计模式》中把 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();

}; 《设计模式》中把 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();

}; QQread.com 推出游戏功略 http://www.qqread.com/netgame/game/index.Html 魔兽世界 跑跑卡丁车 街头篮球 水浒Q传 龙与地下城OL 征服  轩辕剑5 FIFA07 热血江湖 大唐风云 梦幻西游 武林外传 《设计模式》中把 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();

}; QQread.com 推出游戏功略 http://www.qqread.com/netgame/game/index.html 魔兽世界 跑跑卡丁车 街头篮球 水浒Q传 龙与地下城OL 征服  轩辕剑5 FIFA07 热血江湖 大唐风云 梦幻西游 武林外传

Tags:Singleton 实现

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接