• qt基础之全局静态变量


    Q_GLOBAL_STATIC

    用于定义全局静态变量

    #define Q_GLOBAL_STATIC(TYPE, NAME)                                         \
        Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ())
    
    • 1
    • 2

    Q_GLOBAL_STATIC_WITH_ARGS

    带有参数的全局静态变量宏
    在匿名命名空间内定义了命名空间Q_QGS_ ## NAME,该命名空间内定义了

    • 类型:typedef TYPE Type
    • 原子操作变量:QBasicAtomicInt guard
    • 内联函数:Type *innerFunction()
      通过类模板QGlobalStatic来定义全局静态变量
    #define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS)                         \
        namespace { namespace Q_QGS_ ## NAME {                                  \
            typedef TYPE Type;                                                  \
            QBasicAtomicInt guard = Q_BASIC_ATOMIC_INITIALIZER(QtGlobalStatic::Uninitialized); \
            Q_GLOBAL_STATIC_INTERNAL(ARGS)                                      \
        } }                                                                     \
        static QGlobalStatic<TYPE,                                              \
                             Q_QGS_ ## NAME::innerFunction,                     \
                             Q_QGS_ ## NAME::guard> NAME;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    内联函数innerFunction

    是通过Q_GLOBAL_STATIC_INTERNAL来定义的
    采用双重检查方式来初始化全局静态变量。
    原子变量状态值使用枚举

    enum GuardValues {
        Destroyed = -2,
        Initialized = -1,
        Uninitialized = 0,
        Initializing = 1
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    开始原子变量值为Uninitialized,构造完后状态为Initialized,析构时状态为Destroyed

    #define Q_GLOBAL_STATIC_INTERNAL(ARGS)                                  \
        Q_DECL_HIDDEN inline Type *innerFunction()                          \
        {                                                                   \
            static Type *d;                                                 \
            static QBasicMutex mutex;                                       \
            int x = guard.loadAcquire();                                    \
            if (Q_UNLIKELY(x >= QtGlobalStatic::Uninitialized)) {           \
                QMutexLocker locker(&mutex);                                \
                if (guard.load() == QtGlobalStatic::Uninitialized) {        \
                    d = new Type ARGS;                                      \
                    static struct Cleanup {                                 \
                        ~Cleanup() {                                        \
                            delete d;                                       \
                            guard.store(QtGlobalStatic::Destroyed);         \
                        }                                                   \
                    } cleanup;                                              \
                    guard.storeRelease(QtGlobalStatic::Initialized);        \
                }                                                           \
            }                                                               \
            return d;                                                       \
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    类模板QGlobalStatic

    调用innerFunction创建全局静态变量
    操作符(),->或者Type *调用innerFunction函数得到全局变量指针,如果全局变量已经销毁,则返回0
    操作符*返回全局静态变量的引用

    template <typename T, T *(&innerFunction)(), QBasicAtomicInt &guard>
    struct QGlobalStatic
    {
        typedef T Type;
    
        bool isDestroyed() const { return guard.load() <= QtGlobalStatic::Destroyed; }
        bool exists() const { return guard.load() == QtGlobalStatic::Initialized; }
        operator Type *() { if (isDestroyed()) return 0; return innerFunction(); }
        Type *operator()() { if (isDestroyed()) return 0; return innerFunction(); }
        Type *operator->()
        {
          Q_ASSERT_X(!isDestroyed(), "Q_GLOBAL_STATIC", "The global static was used after being destroyed");
          return innerFunction();
        }
        Type &operator*()
        {
          Q_ASSERT_X(!isDestroyed(), "Q_GLOBAL_STATIC", "The global static was used after being destroyed");
          return *innerFunction();
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    应用

    qt中的线程池中使用到

    Q_GLOBAL_STATIC(QThreadPool, theInstance)
    class Q_CORE_EXPORT QThreadPool : public QObject
    {
    	.........
    public:
       	..........
        static QThreadPool *globalInstance();
        ......
    };
    QThreadPool *QThreadPool::globalInstance()
    {
        return theInstance();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    顺为资本许达来:判断风口一看时间点,二看商业本质
    十七、一起学习Lua 错误处理
    探索Semantic Plugins:开启大模型的技能之门
    【回溯算法】77. 组合
    C#中LINQtoObjects、LINQtoDataSet和LINQtoXML
    actionBar 导航栏学习
    Java Reflection中Getters and Setters简介说明
    设计模式学习(十九):访问者模式
    Linux 中 man手册中函数后面括号数字释义
    白给的win+ubuntu双系统重新安装Ubuntu,配置ROS+深度学习开发环境全过程笔记 (一)
  • 原文地址:https://blog.csdn.net/wuli2496/article/details/132687342