接上篇 https://blog.csdn.net/u014491932/article/details/103873073
简单描述了单例设计模式,可以实现单例的简单应用。
这一篇针对实际应用,对上一篇的单例做升级。
1、下面的代码,实现单例的应用,但是缺点在于,这个类是单例,但是如果有很多个类都需要做单例,那不是得写好几个单例类的代码,这样明显太繁琐了。
class QSingleton
{
public:
static inline QSingleton* instanceptr();
private:
QSingleton();
static QSingleton *m_instance;
static QMutex mutex;
};
inline QSingleton* QSingleton::instanceptr()
{
if (NULL == m_instance)
{
QMutexLocker locker(&mutex);
if (NULL == m_instance)
{
m_instance = new QSingleton();
}
}
return m_instance;
}
拓展:使用模板类。这样的话只需要把需要声明成单例模式的类,调用此类模板即可成为一个单例模式的类。
template<class T>
inline T* Singleton<T>::instanceptr()
{
if (NULL == m_instance)
{
QMutexLocker locker(&mutex);
if (NULL == m_instance)
{
m_instance = new Singleton();;
}
}
return m_instance;
}
声明了模板类,由于我们的单例指针是静态变量,外部类无法访问,所以还需要添加一个宏,声明有元类。
#define SINGLETON_CLASS(type) \
friend class Singleton<type>;
在需要做单例的类中使用此宏
class QLanguage
{
Q_OBJECT
public:
void Test();
public:
DECLARE_SINGLETON_CLASS(QLanguage)
};
typedef Singleton<QLanguage> Language;
写完单例类,应用就简单了
Language::instanceptr()->Test();
程序中反复调用此方法,打印log可以发现,instanceptr()方法一直被调用,但是只会创建一次。而QLanguage也成为了全局类,对于上位机软件来说,多界面的全局数据共享提供了有效的优雅并且有效的方式。
2、使用智能指针防止内存泄漏。目前的项目,使用单例是因为需要加载一些外部的资源,这些资源希望被单例调用,但是由于是调用外部资源,就会存在调用失败退出或者返回的情况,而资源没有调用析构被释放等情况,那就会造成内存泄漏。所以对单例又进行了升级
template<class T>
class Singleton
{
public:
static inline T* instanceptr();
private:
QSingleton();
static auto_ptr<T> m_instance;
static QMutex mutex;
};
template<class T>
inline T* Singleton<T>::instanceptr()
{
if (NULL == m_instance.get())
{
QMutexLocker locker(&mutex);
if (NULL == m_instance.get())
{
m_instance = auto_ptr<T>(new T);
}
}
return m_instance.get();
}
资源下载 :获取