Qt 常用设计模式-单例模式2(Singleton)

接上篇 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();    
}

资源下载 :获取

猜你喜欢

转载自blog.csdn.net/u014491932/article/details/105809227