ACE中的设计模式——Singleton

1.          Singleton 模式简介

SingletonGOF 圣经中最简单的一个模式了,主要用于创建在系统中具有唯一实例又需要到处使用的类,实现起来非常简单。

#include <iostream>

using namespace std;

class my_singleton

{

public:

     static my_singleton *instance();

     void show_my_life();

protected:

     my_singleton();

private:

     static my_singleton *m_instance;

};

my_singleton *my_singleton::m_instance = NULL;

my_singleton *my_singleton::instance()

{

     if (m_instance == NULL)

     {

         m_instance = new my_singleton;

     }

     return m_instance;

}

void my_singleton::show_my_life()

{

cout << "i'm living at " << (void*)this << endl;

}

my_singleton::my_singleton(){}

my_singleton::~my_singleton()

{

     if (m_instance != NULL)

     {

         delete m_instance;

         m_instance = NULL;

     }

}

int main()

{

     my_singleton::instance()->show_my_life();

     return 0;

};

2.          ACE 中如何使用Singleton

如上例中,singleton 代码非常简单,也很成熟,但是如果在一个系统中有很多地方都需要使用singleton 模式,则需要写相当多的类似重复代码,枯燥且低效,如果碰巧使用了ACE ,那么使用ACE 封装的singleton ,则可以更加简单:

class normal_test

{

     friend class ACE_Singleton<normal_test, ACE_Null_Mutex>;

public:

     void show_my_life();

private:

     normal_test();

};

normal_test::normal_test(){}

typedef ACE_Singleton<normal_test, ACE_Null_Mutex> NORMAL_TEST;

void normal_test::show_my_life()

{

     cout << "i'm living at " << (void*)this << endl;

}

int ACE_TMAIN(int argc, ACE_TCHAR *argv[])

{

     my_singleton::instance()->show_my_life();

     NORMAL_TEST::instance()->show_my_life();

     return 0;

};

如上所示,获得了以下优点:

1.     代码减少了一半还多,变得更加简洁、清晰,

2.     使用了double-check技术,免费的获得了线程安全。

3.     没有使用继承、虚函数,性能、效率不会受影响。

3.          ACE singleton 是如何实现的?

以下代码节选自ACE 的源代码,为清晰起见,去除了一些无关的宏开关

a)          以下是ACE_Singleton 的定义:

template <class TYPE, class ACE_LOCK>

class ACE_Singleton : public ACE_Cleanup

{

public:

   /// Global access point to the Singleton.

   static TYPE *instance (void);

   /// Cleanup method, used by <ace_cleanup_destroyer> to destroy the

   /// ACE_Singleton.

   virtual void cleanup (void *param = 0);

   /// Dump the state of the object.

   static void dump (void);

protected:

   /// Default constructor.

   ACE_Singleton (void);

   /// Contained instance.

   TYPE instance_;

   /// Pointer to the Singleton (ACE_Cleanup) instance.

   static ACE_Singleton<TYPE, ACE_LOCK> *singleton_;

   /// Get pointer to the Singleton instance.

   static ACE_Singleton<TYPE, ACE_LOCK> *&instance_i (void);

};

b)       看一下instance的实现:

template <class TYPE, class ACE_LOCK> TYPE *

ACE_Singleton<TYPE, ACE_LOCK>::instance (void)

{

   ACE_TRACE ("ACE_Singleton<TYPE, ACE_LOCK>::instance");

   ACE_Singleton<TYPE, ACE_LOCK> *&singleton =

     ACE_Singleton<TYPE, ACE_LOCK>::instance_i ();

   // Perform the Double-Check pattern...

   if (singleton == 0)

     {

           static ACE_LOCK *lock = 0;

           if (ACE_Object_Manager::get_singleton_lock (lock) != 0)

             // Failed to acquire the lock!

             return 0;

           ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *lock, 0);

           if (singleton == 0)

             {

               ACE_NEW_RETURN (singleton, (ACE_Singleton<TYPE, ACE_LOCK>), 0);

               // Register for destruction with ACE_Object_Manager.

               ACE_Object_Manager::at_exit (singleton);

             }

     }

   return &singleton->instance_;

}

说明:double-check技术主要是解决线程安全问题,避免在初始化时多线程重入,导致instance被实例化两次。

c)       再看一下instance_i的实现:

template <class TYPE, class ACE_LOCK> ACE_Singleton<TYPE, ACE_LOCK> *&

ACE_Singleton<TYPE, ACE_LOCK>::instance_i (void)

{

   static ACE_Singleton<TYPE, ACE_LOCK> *singleton_ = 0;

   return singleton_;

}

4.          题外话:

ACE_Singleton 较好的封装了Singleton 模式,对于现代应用系统,一般而言会有相当多的地方需要使用Singleton 模式,如线程池、内存池、数据连接池等,通过ACE_Singleton 类,可以达到简化代码的目的,同时解决GOF 圣经中未提的线程安全的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值