Q_GLOBAL_STATIC
用于定义全局静态变量
#define Q_GLOBAL_STATIC(TYPE, NAME) \
Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ())
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;
内联函数innerFunction
是通过Q_GLOBAL_STATIC_INTERNAL来定义的
采用双重检查方式来初始化全局静态变量。
原子变量状态值使用枚举
enum GuardValues {
Destroyed = -2,
Initialized = -1,
Uninitialized = 0,
Initializing = 1
};
开始原子变量值为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; \
}
类模板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();
}
};
应用
qt中的线程池中使用到
Q_GLOBAL_STATIC(QThreadPool, theInstance)
class Q_CORE_EXPORT QThreadPool : public QObject
{
.........
public:
..........
static QThreadPool *globalInstance();
......
};
QThreadPool *QThreadPool::globalInstance()
{
return theInstance();
}