龙仪的家

导航

<2007年1月>
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910

随笔分类

文章分类

收藏夹

随笔档案

文章档案

统计

我的常用网址

设计模式学习讨论之-单件(singleton)

最近才开始系统学习设计模式。。。有点落伍,爱好者们在这里一起讨论吧。
这里主要关注的是实现以及存在的问题,
单一性是使用singleton的原因,singleton网上的实现一般有这么几种,以下代码从网上摘抄,主要是为了讨论,所有权归原作者所有,请保持原有作者的注释。:)

一,教科书上的标准实现,存在的问题是内存泄漏,多线程方式有问题

class Singleton
{
public:
       
static Singleton * Instance()
       
{
              
if0== _instance)
              
{
                     _instance 
= new Singleton;
              }

              
return _instance;
       }

protected:
       Singleton(
void)
       
{
       }

       
virtual ~Singleton(void)
       
{
       }

       
static Singleton* _instance;
}
;


二,自动回收-缺陷只能一对一,多线程方式有问题

#include <memory>
#include 
<iostream>
using namespace std;
class Singleton
{
public:
       
static Singleton * Instance()
       
{
              
if0== _instance.get())
          
{
                     _instance.reset( 
new Singleton);
              }

              
return _instance.get();
       }

protected:
       Singleton(
void)
     
{
              cout 
<<"Create Singleton"<<endl;
       }

       
virtual ~Singleton(void)
      
{
              cout 
<< "Destroy Singleton"<<endl;
       }

       friend 
class auto_ptr<Singleton>;
       
static auto_ptr<Singleton> _instance;
}
;

三,模版方式-缺陷不支持多线程

 

/********************************************************************

    (c) 2003-2005 C2217 Studio

    Module:    Singleton.h

    Author:     Yangjun D.

    Created:    9/3/2005   23:17

    Purpose:    Implement singleton pattern

    History:

********************************************************************
*/


#pragma once
#include 
<memory>
using namespace std;
using namespace C2217::Win32;
namespace C2217
{
    
namespace Pattern 

 
{
template 
<class T>
class Singleton

{

public:

       
static inline T* instance();

       

private:

       Singleton(
void){}

       
~Singleton(void){}

       Singleton(
const Singleton&){}

       Singleton 
& operator= (const Singleton &){}

       
static auto_ptr<T> _instance;
}
;
template 
<class T>
auto_ptr
<T> Singleton<T>::_instance;
 
  template 
<class T>
 inline T
* Singleton<T>::instance()
{
       
if0== _instance.get())
       
{
              _instance.reset ( 
new T);
       }

       
return _instance.get();

}

 
//Class that will implement the singleton mode, 
//must use the macro in it's delare file
#define DECLARE_SINGLETON_CLASS( type ) 
       friend 
class auto_ptr< type >;
       friend 
class Singleton< type >;
}


}

四,线程安全

/********************************************************************

    (c) 2003-2005 C2217 Studio

    Module:    Singleton.h

    Author:     Yangjun D.

    Created:    9/3/2005   23:17

    Purpose:    Implement singleton pattern

    History:

********************************************************************
*/

#pragma once
#include 
<memory>
using namespace std;
#include 
"Interlocked.h"
using namespace C2217::Win32;

namespace C2217
{
namespace Pattern 
{
template 
<class T>
class Singleton
{
public:
       
static inline T* instance();
       
private:
       Singleton(
void){}
       
~Singleton(void){}
       Singleton(
const Singleton&){}
       Singleton 
& operator= (const Singleton &){}
 
       
static auto_ptr<T> _instance;
       
static CResGuard _rs; 
}
;
 
template 
<class T>
auto_ptr
<T> Singleton<T>::_instance;
 
template 
<class T>
CResGuard Singleton
<T>::_rs; 
 
template 
<class T>
 inline T
* Singleton<T>::instance()
{
       
if0 == _instance.get() )
       
{
              CResGuard::CGuard gd(_rs);
              
if0== _instance.get())
              
{
                     _instance.reset ( 
new T);
              }

       }

       
return _instance.get();
}

 
//Class that will implement the singleton mode, 
//must use the macro in it's delare file
#define DECLARE_SINGLETON_CLASS( type ) 
       friend 
class auto_ptr< type >;
       friend 
class Singleton< type >;
}

}

       CresGuard 类主要的功能是线程访问同步,代码如下:
/*****************************************************************************
Module:  Interlocked.h
Notices: Copyright (c) 2000 Jeffrey Richter
****************************************************************************
*/

 
 
#ragma once
//////////////////////////////////////////////////////////////////////////////
 
// Instances of this class will be accessed by multiple threads. So, 
// all members of this class (except the constructor and destructor) 
// must be thread-safe.
class CResGuard {
public:
   CResGuard()  
{ m_lGrdCnt = 0; InitializeCriticalSection(&m_cs); }
   
~CResGuard() { DeleteCriticalSection(&m_cs); }
 
   
// IsGuarded is used for debugging
   BOOL IsGuarded() const return(m_lGrdCnt > 0); }
 
public:
   
class CGuard {
   
public:
      CGuard(CResGuard
& rg) : m_rg(rg) { m_rg.Guard(); };
      
~CGuard() { m_rg.Unguard(); }
 
   
private:
      CResGuard
& m_rg;
   }
;
 
private:
   
void Guard()   { EnterCriticalSection(&m_cs); m_lGrdCnt++; }
   
void Unguard() { m_lGrdCnt--; LeaveCriticalSection(&m_cs); }
 
   
// Guard/Unguard can only be accessed by the nested CGuard class.
   friend class CResGuard::CGuard;
 
private:
   CRITICAL_SECTION m_cs;
   
long m_lGrdCnt;   // # of EnterCriticalSection calls
}
;
 
 
//////////////////////////////////////////////////////////////////////////////
//使用方法
比如你有一个需要实现单件模式的类,就应该这样实现:
#pragma once
#include 
"singleton.h"
using namespace C2217::Pattern;
 
class ServiceManger
{
public:
       
void Run()
       
{
       }

private:
       ServiceManger(
void)
       
{
       }

       
virtual ~ServiceManger(void)
       
{
       }

       DECLARE_SINGLETON_CLASS(ServiceManger);
}
;
 
typedef Singleton
<ServiceManger> SSManger;
 
在使用的时候很简单,跟一般的Singleton实现的方法没有什么不同。
int _tmain(int argc, _TCHAR* argv[])
{
        SSManger::instance()
->Run();
}


五,超简单方法-有人说这个不支持多线程,个人觉得应该没问题吧,在这里求证一下

template <class T> 
class Singleton 

 
public
 
static inline T& instance() 
 

  
static T _instance; 
  
return _instance; 
 }
 

protected:
 Singleton(
void); 
 
~Singleton(void); 
private:
 Singleton(
const Singleton<T>&); 
 Singleton
<T>& operator= (const Singleton<T> &); 
}

posted on 2007-01-29 10:24 龙仪 阅读(1108) 评论(4)  编辑 收藏

评论

# re: 设计模式学习讨论之-单件(songleton) 2007-01-29 17:17 sevencat

最后一个支持多线程吧。
不然所有的函数类的全局变量都不是线程安全的,我一般也就用最后一种方法。

# re: 设计模式学习讨论之-单件(songleton) 2007-02-01 17:05 网络电话

支持支持

# re: 设计模式学习讨论之-单件(songleton) 2007-02-05 10:10 小明

最后一个不是多线程安全的

因为静态变量的构造函数会在第一次进入函数时被调用,可能会被调用两次。

不过可以在主线程中先调用一次,保证初始化成功后,就没有问题了。

# re: 设计模式学习讨论之-单件(songleton) 2007-02-05 10:11 小明

提醒一下,标题中的songleton写错了

标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]