一:题目
实现一个类, 我们只能生成该类的一个实例。
二:题目分析
该题也是常见的题目。实现单例,首先单例模式是设计模式中最常见的模式之一。设计单例模式的话,通常需要注意以下几点:
- 类的构造函数、拷贝构造函数、赋值函数声明为受保护成员或私有成员。
- 获取单例的函数设置为静态成员函数
- 注意线程安全性
- 双层判断可以提高获取单例类实例的效率。
三:源码设计
结合C++语言的特性,这里我们使用了模板类来完成单例模式的设计。该类为单例类的基类,继承该类的子类都可以成为一个单例类。这种设计具有平台化的效果。
/*******************************
** 作者: 非正经程序员
** csdn: https://blog.youkuaiyun.com/u012058778
** 公众号: 非正经码农
** 描述: 无
**Copyright ©2020 非正经程序员版权所有
*******************************/
#pragma once
template <typename T>
class ESingleton {
public:
static T* GetInstance();
static void ReleaseInstance();
protected:
ESingleton() {}
virtual ~ESingleton() {}
private:
ESingleton(const ESingleton<T>& other);
ESingleton<T>& operator=(const ESingleton<T>& other);
private:
static T* m_pInstance;
static IRWMutex m_Mutex;
};
template <typename T>
IRWMutex ESingleton<T>::m_Mutex;
template <typename T>
T* ESingleton<T>::m_pInstance = NULL;
template <typename T>
T* ESingleton<T>::GetInstance() {
if (m_pInstance != NULL) {
return m_pInstance;
}
m_Mutex.lock();
if (m_pInstance == NULL) {
m_pInstance = new T();
}
m_Mutex.unlock();
return m_pInstance;
}
template <typename T>
void ESingleton<T>::ReleaseInstance() {
if (m_pInstance != NULL) {
m_Mutex.lock();
RELEASE_POINTER(m_pInstance);
m_Mutex.unlock();
}
}
如上所以,该继承该模板类的子类就有了单例的属性。如下:
class EFormatManual : public ESingleton<EFormatManual> {
friend class ESingleton<EFormatManual>;
public:
protected:
EFormatManual() {}
~EFormatManual(){}
}
EFormatManual类就是一个线程安全的单例类。当然还有单例模式也分为懒汉式和饿汉式单例,这里不做过多赘述。