现在的位置: 首页 > 综合 > 正文

设计模式之——Singleton(单令模式)

2013年12月07日 ⁄ 综合 ⁄ 共 2110字 ⁄ 字号 评论关闭

单令模式用于保证一个类只有一个实例,C++最常见的写法为

class CSingleton
{
CSingleton() {}
~CSingleton() {}
CSingleton(const CSingleton&);
CSingleton& operator= (const CSingleton&);

public:
    static CSingleton& Instance()
    { static CSingleton obj; return obj; }

……
};

通过CSingleton::Instance ()来获得唯一实例的引用。单例模式也许是设计模式模式中最简单的了,但并不然,这里仍有需要解决的问题:

1:多线程环境下,单例对象构造问题

最直接的方法Instance()函数互斥访问,

// 采用双检测来确保多线程安全
template <class T>
class YKSingleton
{
	YKSingleton() {}
	~YKSingleton() {}
	YKSingleton(const YKSingleton&);
	YKSingleton& operator(const YKSingleton&);

	static T* m_pObj;
public:
	static T& Instance()
	{
		if (!m_pObj)
		{
			YKScopedLock<YKFastMutex> lock(g_mutex);
			if (!m_pObj)
				m_pObj = new T;
		}

		return *m_pObj;
	}
};

template <class T> YKSingleton<T>::m_pObj = YK_NULL;

2:因释放顺序,导致引用不存在的单例对象

解决方法:写个类来管理所有的单例对象,将单例对象存入vector中,先创建的单例对象后释放,来解决问题。

class UTIL_API YKSingletonManager
{
	class CHolderSingleton
	{
	public:
		CHolderSingleton() {}
		virtual ~CHolderSingleton() {}
	};

	template <class T>
	class CSingleton : public CHolderSingleton
	{
	public:
		CSingleton(T* pObj) : m_pObj(pObj) {}
		virtual ~CSingleton() { delete m_pObj; }

		T* m_pObj;
	};

	typedef std::vector<CHolderSingleton*>	obj_type;
	typedef obj_type::iterator				obj_iter;
	typedef obj_type::reverse_iterator		obj_rIter;

	YKSingletonManager(void);
	~YKSingletonManager(void);
	YKSingletonManager(const YKSingletonManager&);
	YKSingletonManager& operator= (const YKSingletonManager&);

	static YKSingletonManager& Instance() { static YKSingletonManager obj; return obj; }

	template <class T>
	void Insert(T* pObj) {
		m_singletons.push_back(new CSingleton<T>(pObj));
	}

	template <class T> friend class YKSingleton;
private:
	obj_type m_singletons;
};

提供给外界使用的单例框架

template <class T>
class YKSingleton
{
protected:
	YKSingleton() {}
	~YKSingleton() {}
	YKSingleton(const YKSingleton&);
	YKSingleton& operator= (const YKSingleton&);
	static T* m_pSingletonObj;

	friend class YKSingletonManager::CSingleton<T>;
public:
	static T& Instance()
	{
		if (!m_pSingletonObj)
		{
#ifdef YK_THREAD_MULTI
			YKScopedLock<YKFastMutex> lock(g_mutex);
			if (!m_pSingletonObj)
			{
#endif // YK_THREAD_MULTI
				m_pSingletonObj = new T();
				YKSingletonManager::Instance().Insert<T>(m_pSingletonObj);
#ifdef YK_THREAD_MULTI
			}
#endif // YK_THREAD_MULTI
		}
		return *m_pSingletonObj;
	}
};

template <class T> T* YKSingleton<T>::m_pSingletonObj = YK_NULL;

使用方法:

class MyObj : public YKSingleton<MyObj>
{
}
【上篇】
【下篇】

抱歉!评论已关闭.