分类: C/C++
2008-07-02 15:22:48
1. Singleton模式简介
Singleton是GOF圣经中最简单的一个模式了,主要用于创建在系统中具有唯一实例又需要到处使用的类,实现起来非常简单。
#include
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_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
/// 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
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圣经中未提的线程安全的问题。后续我会继续就ACE中的使用的设计模式提出来与大家进行探讨、学习。