• Qt 单例模式的实现(4种方法)


    最简单的写法:

    1 static MyClass* MyClass::Instance()
    2 {
    3     static MyClass inst;
    4     return &inst;
    5 }

    过去很长一段时间一直都这么写,简单粗暴有效。但是直接声明静态对象会使编译出的可执行文件增大,也有可能出现其他的一些问题,所以利用了Qt自带的智能指针QScopedPointer和线程锁QMutex,改成了需要时才动态初始化的模式:

     1 static MyClass* MyClass::Instance()
     2 {
     3     static QMutex mutex;
     4     static QScopedPointer<MyClass> inst;
     5     if (Q_UNLIKELY(!inst)) {
     6         mutex.lock();
     7         if (!inst) {
     8             inst.reset(new MyClass);
     9         }
    10         mutex.unlock();
    11     }
    12     return inst.data();
    13 }

    既保证了线程安全又防止了内存泄漏,效率也没降低太多,简直完美。

    可惜每次都要重复这么几行实在麻烦,于是写了一个模板类:

     1 template <class T>
     2 class Singleton
     3 {
     4 public:
     5     static T* Instance()
     6     {
     7         static QMutex mutex;
     8         static QScopedPointer<T> inst;
     9         if (Q_UNLIKELY(!inst)) {
    10             mutex.lock();
    11             if (!inst) {
    12                 inst.reset(new T);
    13             }
    14             mutex.unlock();
    15         }
    16         return inst.data();
    17     }
    18 };

    使用的时候直接这样——

    MyClass* inst = Singleton<MyClass>::Instance();

    除了用模板类,还可以利用c++中强大的宏:

     1 #define DECLARE_SINGLETON(Class) 
     2 Q_DISABLE_COPY(Class) 
     3 public: 
     4     static Class* Instance() 
     5     { 
     6         static QMutex mutex; 
     7         static QScopedPointer<Class> inst; 
     8         if (Q_UNLIKELY(!inst)) { 
     9             mutex.lock(); 
    10             if (!inst) inst.reset(new Class); 
    11             mutex.unlock(); 
    12         } 
    13         return inst.data(); 
    14     }

    然后声明的时候,填加一行这个宏:

    1 class MyClass
    2 {
    3     DECLARE_SINGLETON(MyClass);    // 声明单例模式
    4     //...
    5 }

    好评好评。

    当然,为了要保证真的是单例模式,还要把构造函数限制为private,不然以后什么时候忘记了这码事,在外面又new了一下就不好了。

    另外Qt本身自带了一个宏Q_GLOBAL_STATIC,也有类似单例模式的效果,QThreadPool::globalInstance()函数的实现就是利用了这个宏。不过它的主要用处是声明全局变量,和Singleton还是有差别的。

  • 相关阅读:
    1118诗名,诗词形式,类别实体导入
    1119飞花令句子,好友关系导入
    1116五言诗生成&古今地名标注与展示
    1120地点实体与事件实体导入
    1121实体导入总结
    1111诗人生平信息提取
    1114诗词收集&藏头诗生成&Snownlp正负情感分析
    1112全体诗人个人生平提取
    1113七言诗词收集与LSTM自动写诗
    WPF ListView DataGrid日期时间类型格式转换
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14919155.html
Copyright © 2020-2023  润新知