▲
-
Header: QGlobalStatic
-
Since: Qt 5.1
-
CMake:
find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
-
qmake: QT += core
Detailed Description▲
The QGlobalStatic class is the front-end API exported when Q_GLOBAL_STATIC() is used. See the documentation for the macro for a discussion on when to use it and its requirements.
Normally, you will never use this class directly, but instead you will use the Q_GLOBAL_STATIC() or Q_GLOBAL_STATIC_WITH_ARGS() macros, as follows:
Q_GLOBAL_STATIC(MyType, staticType)
The above example creates an object of type QGlobalStatic called staticType. After the above declaration, the staticType object may be used as if it were a pointer, guaranteed to be initialized exactly once. In addition to the use as a pointer, the object offers two methods to determine the current status of the global: exists() and isDestroyed().
See Also▲
See also Q_GLOBAL_STATIC(), Q_GLOBAL_STATIC_WITH_ARGS()
Member Type Documentation▲
[alias] QGlobalStatic::Type▲
This type is equivalent to the Type parameter passed to the Q_GLOBAL_STATIC() or Q_GLOBAL_STATIC_WITH_ARGS() macros. It is used in the return types of some functions.
Member Function Documentation▲
bool QGlobalStatic::exists() const▲
This function returns true if the global static object has already completed initialization (that is, if the constructor for the type has already returned). In specific, note that this function returns false if the initialization is still in progress.
Once this function has returned true once, it will never return false again until either the program is restarted or the plugin or library containing the global static is unloaded and reloaded.
This function is safe to call at any point in the program execution: it cannot fail and cannot cause a deadlock. Additionally, it will not cause the contents to be created if they have not yet been created.
This function is useful if one can determine the initial conditions of the global static object and would prefer to avoid a possibly expensive construction operation.
For example, in the following code sample, this function is used to short-circuit the creation of the global static called globalState and returns a default value:
Q_GLOBAL_STATIC(MyType, globalState)
QString someState()
{
if
(globalState.exists())
return
globalState-&
gt;someState;
return
QString();
}
Thread-safety notice: this function is thread-safe in the sense that it may be called from any thread at any time and will always return a valid reply. But due to the non-atomic nature of construction, this function may return false for a short time after the construction has completed.
Memory ordering notice: this function does not impose any memory ordering guarantees. That is instead provided by the accessor functions that return the pointer or reference to the contents. If you bypass the accessor functions and attempt to access some global state set by the constructor, be sure to use the correct memory ordering semantics provided by QAtomicInt or QAtomicPointer.
See Also▲
See also isDestroyed()
bool QGlobalStatic::isDestroyed() const▲
This function returns true if the global static object has already completed destruction (that is, if the destructor for the type has already returned). In specific, note that this function returns false if the destruction is still in progress.
Once this function has returned true once, it will never return false again until either the program is restarted or the plugin or library containing the global static is unloaded and reloaded.
This function is safe to call at any point in the program execution: it cannot fail and cannot cause a deadlock. Additionally, it will not cause the contents to be created if they have not yet been created.
This function is useful in code that may be executed at program shutdown, to determine whether the contents may still be accessed or not.
See Also▲
See also exists()
QGlobalStatic::Type *QGlobalStatic::operator QGlobalStatic::Type *()▲
This function returns the address of the contents of this global static. If the contents have not yet been created, they will be created thread-safely by this function. If the contents have already been destroyed, this function will return a null pointer.
This function can be used, for example, to store the pointer to the contents of the global static in a local variable, thus avoiding multiple calls to the function. The implementation of Q_GLOBAL_STATIC() is quite efficient already, but in performance-critical sections it might be useful to help the compiler a little. For example:
Q_GLOBAL_STATIC(MyType, globalState)
QString someState()
{
MyType *
state =
globalState;
if
(!
state) {
// we're in a post-destruction state
return
QString();
}
if
(state-&
gt;condition)
return
state-&
gt;value1;
else
return
state-&
gt;value2;
}
See Also▲
See also operator->(), operator*()
QGlobalStatic::Type &QGlobalStatic::operator*()▲
This function returns a reference to the contents of this global static. If the contents have not yet been created, they will be created thread-safely by this function.
This function does not check if the contents have already been destroyed. If this function is called after the object has been destroyed, it will return an invalid reference that must not be used.
QGlobalStatic::Type *QGlobalStatic::operator->()▲
This function returns the address of the contents of this global static. If the contents have not yet been created, they will be created thread-safely by this function.
This function does not check if the contents have already been destroyed and will never return null. If this function is called after the object has been destroyed, it will return a dangling pointer that should not be dereferenced.
Macro Documentation▲
[since 6.3] Q_APPLICATION_STATIC(Type, VariableName, ...)▲
This macro extends Q_GLOBAL_STATIC and creates a global and static object of type QGlobalStatic, of name VariableName, initialized by the variadic arguments, and that behaves as a pointer to Type, where the actual lifetime of the type is bound to the QCoreApplication. The object created by Q_APPLICATION_STATIC initializes itself on the first use, which means that it will not increase the application or the library's load time. Additionally, the object is initialized in a thread-safe manner on all platforms.
In contrast to Q_GLOBAL_STATIC where the type is only meant to be destroyed at program exit, here the actual lifetime of the type is bound to the lifetime of the QCoreApplication. This makes it ideal to store semi-static QObjects, which should also be destroyed once the QCoreApplication is destroyed. This means the type will get deleted once the QCoreApplication emits the destroyed signal. However, as long as the actual holder is still in the initialized state, the type will be recreated when it's accessed again once a new QCoreApplication has been created.
Since the value is bound to the QCoreApplication, it should only ever be accessed if there is a valid QCoreApplication::instance(). Accessing this object before QCoreApplication is created or after it's destroyed will produce warnings and may have unpredictable behavior.
The typical use of this macro is as follows, in a global context (that is, outside of any function bodies):
Q_APPLICATION_STATIC(MyQObjectType, staticType, "some string"
, function())
Do note that the arguments passed in variadic fashion to this macro are evaluated every time the object is constructed, so in the above example, the function function will be called more than once if the object is recreated.
Aside from the value also being bound to the lifetime of the QCoreApplication, this macro behaves identically to Q_GLOBAL_STATIC(). Please see that macro's documentation for more information.
This macro was introduced in Qt 6.3.
See Also▲
See also Q_GLOBAL_STATIC, QGlobalStatic
[since 5.1] Q_GLOBAL_STATIC(Type, VariableName, ...)▲
Creates a global and static object of type QGlobalStatic, of name VariableName and that behaves as a pointer to Type. The object created by Q_GLOBAL_STATIC initializes itself on the first use, which means that it will not increase the application or the library's load time. Additionally, the object is initialized in a thread-safe manner on all platforms.
Since Qt 6.3, this macro admits variadic arguments, which are used to initialize the object, thus making the need for Q_GLOBAL_STATIC_WITH_ARGS unnecessary. Please note the arguments do not require an extra set of parentheses, unlike the older macro.
The typical use of this macro is as follows, in a global context (that is, outside of any function bodies):
Q_GLOBAL_STATIC(MyType, staticType)
This macro is intended to replace global static objects that are not POD (Plain Old Data, or in C++11 terms, not made of a trivial type), hence the name. For example, the following C++ code creates a global static:
static
MyType staticType;
Compared to Q_GLOBAL_STATIC, and assuming that MyType is a class or struct that has a constructor, a destructor, or is otherwise non-POD, the above has the following drawbacks:
-
it requires load-time initialization of MyType (that is, the default constructor for MyType is called when the library or application is loaded);
-
the type will be initialized even if it is never used;
-
the order of initialization and destruction among different translation units is not determined, leading to possible uses before initialization or after destruction;
The Q_GLOBAL_STATIC macro solves all of the above problems by guaranteeing thread-safe initialization on first use and allowing the user to query for whether the type has already been destroyed, to avoid the use-after-destruction problem (see QGlobalStatic::isDestroyed()).
Constructor and Destructor▲
For Q_GLOBAL_STATIC, the type Type must be publicly default-constructible and publicly destructible. For Q_GLOBAL_STATIC_WITH_ARGS(), there must be a public constructor that matches the arguments passed.
It is not possible to use Q_GLOBAL_STATIC with types that have protected or private default constructors or destructors (for Q_GLOBAL_STATIC_WITH_ARGS(), a protected or private constructor matching the arguments). If the type in question has those members as protected, it is possible to overcome the issue by deriving from the type and creating public a constructor and destructor. If the type has them as private, a friend declaration is necessary before deriving.
For example, the following is enough to create MyType based on a previously-defined MyOtherType which has a protected default constructor and/or a protected destructor (or has them as private, but that defines MyType as a friend).
class
MyType : public
MyOtherType {
}
;
Q_GLOBAL_STATIC(MyType, staticType)
No body for MyType is required since the destructor is an implicit member and so is the default constructor if no other constructors are defined. For use with Q_GLOBAL_STATIC_WITH_ARGS(), however, a suitable constructor body is necessary:
class
MyType : public
MyOtherType
{
public
:
MyType(int
i) : MyOtherType(i) {}
}
;
Q_GLOBAL_STATIC_WITH_ARGS(MyType, staticType, (42
))
Alternatively, if the compiler supports C++11 inheriting constructors, one could write:
class
MyType : public
MyOtherType
{
public
:
using
MyOtherType::
MyOtherType;
}
;
Q_GLOBAL_STATIC_WITH_ARGS(MyType, staticType, (42
))
Placement▲
The Q_GLOBAL_STATIC macro creates a type that is necessarily static, at the global scope. It is not possible to place the Q_GLOBAL_STATIC macro inside a function (doing so will result in compilation errors).
More importantly, this macro should be placed in source files, never in headers. Since the resulting object is has static linkage, if the macro is placed in a header and included by multiple source files, the object will be defined multiple times and will not cause linking errors. Instead, each translation unit will refer to a different object, which could lead to subtle and hard-to-track errors.
Non-recommended uses▲
Note that the macro is not recommended for use with types that are POD or that have C++11 constexpr constructors (trivially constructible and destructible). For those types, it is still recommended to use regular static, whether global or function-local.
This macro will work, but it will add unnecessary overhead.
Reentrancy, Thread-safety, Deadlocks, and Exception-safety on Construction▲
The Q_GLOBAL_STATIC macro creates an object that initializes itself on first use in a thread-safe manner: if multiple threads attempt to initialize the object at the same time, only one thread will proceed to initialize, while all other threads wait for completion.
If the initialization process throws an exception, the initialization is deemed not complete and will be attempted again when control reaches any use of the object. If there are any threads waiting for initialization, one of them will be woken up to attempt to initialize.
The macro makes no guarantee about reentrancy from the same thread. If the global static object is accessed directly or indirectly from inside the constructor, a deadlock will surely happen.
In addition, if two Q_GLOBAL_STATIC objects are being initialized on two different threads and each one's initialization sequence accesses the other, a deadlock might happen. For that reason, it is recommended to keep global static constructors simple or, failing that, to ensure that there's no cross-dependency of uses of global static during construction.
Destruction▲
If the object is never used during the lifetime of the program, aside from the QGlobalStatic::exists() and QGlobalStatic::isDestroyed() functions, the contents of type Type will not be created and there will not be any exit-time operation.
If the object is created, it will be destroyed at exit-time, similar to the C atexit function. On most systems, in fact, the destructor will also be called if the library or plugin is unloaded from memory before exit.
Since the destruction is meant to happen at program exit, no thread-safety is provided. This includes the case of plugin or library unload. In addition, since destructors are not supposed to throw exceptions, no exception safety is provided either.
However, reentrancy is permitted: during destruction, it is possible to access the global static object and the pointer returned will be the same as it was before destruction began. After the destruction has completed, accessing the global static object is not permitted, except as noted in the QGlobalStatic API.
Notes▲
This macro was introduced in Qt 5.1.
See Also▲
See also Q_GLOBAL_STATIC_WITH_ARGS(), Q_APPLICATION_STATIC(), QGlobalStatic
Obsolete Members for QGlobalStatic▲
The following members of class QGlobalStatic are deprecated. We strongly advise against using them in new code.
Obsolete Member Function Documentation▲
QGlobalStatic::Type *QGlobalStatic::operator()()▲
This function is deprecated. We strongly advise against using it in new code.
This function returns the address of the contents of this global static. If the contents have not yet been created, they will be created thread-safely by this function. If the contents have already been destroyed, this function will return a null pointer.
This function is equivalent to operator Type *(). It is provided for compatibility with the private Q_GLOBAL_STATIC implementation that existed in Qt 4.x and 5.0. New code should avoid using it and should instead treat the object as a smart pointer.
Obsolete Macro Documentation▲
[since 5.1] Q_GLOBAL_STATIC_WITH_ARGS(Type, VariableName, Arguments)▲
This macro is deprecated. We strongly advise against using it in new code.
Creates a global and static object of type QGlobalStatic, of name VariableName, initialized by the arguments Arguments and that behaves as a pointer to Type. The object created by Q_GLOBAL_STATIC_WITH_ARGS initializes itself on the first use, which means that it will not increase the application or the library's load time. Additionally, the object is initialized in a thread-safe manner on all platforms.
The typical use of this macro is as follows, in a global context (that is, outside of any function bodies):
Q_GLOBAL_STATIC_WITH_ARGS(MyType, staticType, (42
, "Hello"
, "World"
))
The Arguments macro parameter must always include the parentheses or, if C++11 uniform initialization is allowed, the braces. The above call is equivalent to
Q_GLOBAL_STATIC(MyType, staticType, 42
, "Hello"
, "World"
)
Aside from the actual initialization of the contents with the supplied arguments, this macro behaves identically to Q_GLOBAL_STATIC(). Please see that macro's documentation for more information.
This macro was introduced in Qt 5.1.
See Also▲
See also Q_GLOBAL_STATIC(), QGlobalStatic