ACE中的单例模式

ACE中的单例模式

ACE中的单例就是利用ACE_Singleton这个类去管理其他类的单例,需要实现一个单例类的时候只需要做两件事:

  1. 将自己的类T的构造和析构函数都私有化,为了防止用户去生成和释放对象。
  2. 然后把ACE_Singleton<T,ACE_LOCK>类声明为自己的友元类,然后就可以调用友元类的instance方法获得自己的单实例,这个单实例不用自己管理,可以使用typedef来定义看起来就像调用自身方法一样的。

ACE_Object_Manager能够对单例实例进行资源管理,在进程退出的时候,自动清理单例对象,而不用手动来释放。

template <class TYPE, class ACE_LOCK>
class ACE_Singleton : public ACE_Cleanup//继承ACE_Cleanup,是为了单例会交给系统释放
{
public:
  /// Global access point to the Singleton.
  static TYPE *instance (void);//返回传入的类类型的实例对象

  /// Cleanup method, used by @c ace_cleanup_destroyer to destroy the
  /// ACE_Singleton.
  virtual void cleanup (void *param = 0);

  /// Explicitly delete the Singleton instance.
  static void close (void);

  /// Dump the state of the object.
  static void dump (void);

  /// Declare the dynamic allocation hooks.
  ACE_ALLOC_HOOK_DECLARE;

protected:
  /// Default constructor.
  ACE_Singleton (void);//私有化构造函数

  /// Contained instance.
  TYPE instance_;//管理一个单例是TYPE类型的

#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
  /// Pointer to the Singleton (ACE_Cleanup) instance.
  static ACE_Singleton<TYPE, ACE_LOCK> * singleton_;//该类对象静态对象
#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */

  /// Get pointer to the Singleton instance.
  static ACE_Singleton<TYPE, ACE_LOCK> *&instance_i (void);
};





template <class TYPE, class ACE_LOCK> 
void ACE_Singleton<TYPE, ACE_LOCK>::dump (void)
{
#if defined (ACE_HAS_DUMP)
  ACE_TRACE ("ACE_Singleton<TYPE, ACE_LOCK>::dump");

#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
  ACELIB_DEBUG ((LM_DEBUG,  ACE_TEXT ("instance_ = %x"),
              ACE_Singleton<TYPE, ACE_LOCK>::instance_i ()));
  ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
#endif /* ACE_HAS_DUMP */
}

template <class TYPE, class ACE_LOCK> 
ACE_Singleton<TYPE, ACE_LOCK> *& ACE_Singleton<TYPE, ACE_LOCK>::instance_i (void)
{
#if defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
  // Pointer to the Singleton instance.  This works around a bug with
  // G++ and it's (mis-)handling of templates and statics...
  static ACE_Singleton<TYPE, ACE_LOCK> *singleton_ = 0;

  return singleton_;
#else
  return ACE_Singleton<TYPE, ACE_LOCK>::singleton_;
#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
}

//这个方法返回其他类的单实例
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)
    {
      if (ACE_Object_Manager::starting_up () ||
          ACE_Object_Manager::shutting_down ())
        {
          // The program is still starting up, and therefore assumed
          // to be single threaded.  There's no need to double-check.
          // Or, the ACE_Object_Manager instance has been destroyed,
          // so the preallocated lock is not available.  Either way,
          // don't register for destruction with the
          // ACE_Object_Manager:  we'll have to leak this instance.

          ACE_NEW_RETURN (singleton, (ACE_Singleton<TYPE, ACE_LOCK>), 0);
        }
      else
        {
#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
          // Obtain a lock from the ACE_Object_Manager.  The pointer
          // is static, so we only obtain one per ACE_Singleton
          // instantiation.
#if defined(ACE_FACE_SAFETY_BASE)
          static ACE_LOCK the_lock;
          static ACE_LOCK *lock = &the_lock;
#else /* ACE_FACE_SAFETY_BASE */
          static ACE_LOCK *lock = 0;
#endif /* ACE_FACE_SAFETY_BASE */
          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)
            {
#endif /* ACE_MT_SAFE */
              ACE_NEW_RETURN (singleton, (ACE_Singleton<TYPE, ACE_LOCK>), 0);

              // Register for destruction with ACE_Object_Manager.
#if !defined (ACE_MT_SAFE) || (ACE_MT_SAFE == 0)
              ACE_Object_Manager::at_exit (singleton, 0, typeid (TYPE).name ());
#else
              ACE_Object_Manager::at_exit (singleton, &lock,
                                           typeid (TYPE).name ());
            }
#endif /* ACE_MT_SAFE */
        }
    }

  return &singleton->instance_;//singleton是ACE_Singleton<TYPE, ACE_LOCK>的单例,返回instance_就是T的单例
}

template <class TYPE, class ACE_LOCK> void
ACE_Singleton<TYPE, ACE_LOCK>::cleanup (void *param)
{
  ACE_Object_Manager::remove_at_exit (this);
  delete this;
  ACE_Singleton<TYPE, ACE_LOCK>::instance_i () = 0;

#if !defined ACE_MT_SAFE || ACE_MT_SAFE == 0 || defined ACE_FACE_SAFETY_BASE
  ACE_UNUSED_ARG (param);
#else
  if (param)
    {
      ACE_LOCK **lock = static_cast<ACE_LOCK **> (param);
      *lock = 0;
    }
#endif
}

template <class TYPE, class ACE_LOCK> void
ACE_Singleton<TYPE, ACE_LOCK>::close (void)
{
  ACE_Singleton<TYPE, ACE_LOCK> *&singleton =
    ACE_Singleton<TYPE, ACE_LOCK>::instance_i ();

  if (singleton)
    {
      singleton->cleanup ();
      ACE_Singleton<TYPE, ACE_LOCK>::instance_i () = 0;
    }
}

#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
// Pointer to the Singleton instance.
template <class TYPE, class ACE_LOCK> 
ACE_Singleton<TYPE, ACE_LOCK>* ACE_Singleton<TYPE, ACE_LOCK>::singleton_ = 0;

class Ex
{                                                                               {
    friend class ACE_Singleton<Ex, ACE_Null_Mutex>; //声明为友元类,那么这个类就可以访问该类的私有成员
private:
    Ex () { cout << "Ex constructed" << endl; }
    ~Ex () { cout << "Ex destroyed" << endl; }
};
typedef ACE_Singleton<Ex, ACE_Null_Mutex> Ex; 

这样就可以通过Ex.instance()来获得单例实例了,注意返回的是Ex类对象。

吐槽 :

这个庞大的库,代码写的真的不咋地,比起其他优秀的开源组件有点差距,看ACE的代码真的心累,本人也很菜,哈哈哈,但还是想吐槽一下,不过ACE还是有很多值得学习的地方!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值