|
// Singleton.cpp : 定义控制台应用程序的入口点。
//
/************************************************************************/ /* 意图: /* 保证一个类只有一个实例,并提供一个访问它的全局访问点 /* /* 适用性: /* 1. 同上 /* 2. 这个实例应该是通过子类化可扩展的,并且用户无需更改基类代码 /* /* 效果: /* 1. 对惟一实例的受控访问 /* 2. 缩小名空间。这是对全局变量的一种替代策略。 /* 3. 可继承,可生成多个实例(不同类型) /* 4. 比类操作更灵活,相对类的静态函数,独体类对象的函数还可以体现多态性 /* /* Author: kubobo /* Date: 2006-11-4 /************************************************************************/ #include "stdafx.h" #include <iostream>
//模拟多线程情况的加锁操作
#define MUTEX_LOCK() #define MUTEX_UNLOCK()
using namespace std;
/************************************************************************/ /* Declaration */ /************************************************************************/ template<typename T> class Singleton { public: //本来需要protected的访问权限的,作用有两个:
//1. 子类继承的需要
//2. 防止用户自行定义对象,保证独体类的惟一性
//然而有了下面的virtual ~Singleton() = 0 {}
//Singleton()完全解放了,呵呵~ 见下方。
Singleton() {}
//让Singleton成为抽象类,防止实例化一个无意义的基类对象(什么都没做),
//使得只有通过继承方式实现独体类对象。有了这个限制,Singleton的构造函数
//可以不用写了,或者标示为public还是private都无所谓了。
virtual ~Singleton() = 0 {}
public: static T *Instance(); static void Destroy();
private: //使用volatile,防止编译器优化,保持变量的原子性操作
volatile static T *m_pSingleton; };
class MySingleton : public Singleton<MySingleton> { //使父类成为友元类,否则不能在外部new出子类对象。
//当然,如果下面的构造函数为public,此处的friend则多余了,
//但是同时也给了用户自行创建对象的权利,不明智,嗯。
friend class Singleton<MySingleton>;
//防止用户自行定义对象,保证独体类的惟一性
private: MySingleton() {}
//本来不用写析构函数也可以,但是想想如果main中出现
//delete MySingleton::Instance();
//可怎么办?还是婆婆妈妈一点吧~!
virtual ~MySingleton() {}
public: void PrintOut(); };
/************************************************************************/ /* Implementation */ /************************************************************************/ template<typename T> volatile T *Singleton<T>::m_pSingleton = NULL;
template<typename T> T *Singleton<T>::Instance() { //此处需要两个if,其实还是很有道理的^_^
if (NULL == m_pSingleton) { MUTEX_LOCK();//互斥锁。要么进去,要么阻塞
if (NULL == m_pSingleton) { m_pSingleton = new T(); } } MUTEX_UNLOCK();//解锁,让阻塞的能进去
return (T *)m_pSingleton;//不强制转换的话,VC8编译通不过。也许太严格了,唉~
}
template<typename T> void Singleton<T>::Destroy() { //一般由程序保证最后只调用销毁函数一次,不必加锁了
if (m_pSingleton) { delete m_pSingleton; m_pSingleton = NULL; } }
void MySingleton::PrintOut() { cout << "MySingleton::PrintOut()" << endl; }
/************************************************************************/ /* main */ /************************************************************************/ int _tmain(int argc, _TCHAR* argv[])//VC8的开发环境,请自行修改。PS:VC8真是好东东~
{ MySingleton::Instance()->PrintOut(); MySingleton::Destroy();
return 0; }
//后记:
//感觉自己写的这个Singleton比较繁琐,因为考虑了很多东西,正因为此,它也不是一次就写成的。
//实际上,我们用的最多的还是简单的方式,即以非继承的形式来使用Singleton模式。
//虽然“四人帮”一直强调继承的方式来使用,
//但至少在目前,我见到的一些真实系统中也都是使用简单的非继承方式。当然,
//使用了一些优化的办法来缩减工作量,比如用宏。嗯,不多说了,大家自己动手实践一下,
//只要符合意图中的两点要求就是Singleton,有好的创意请跟我交流哦~ ^_^
|