Sur cette page

QGlobalStatic Struct

template <typename Holder> struct QGlobalStatic

La classe QGlobalStatic est utilisée pour mettre en œuvre un objet statique global. Plus d'informations...

En-tête : #include <QGlobalStatic>
CMake : find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake : QT += core

Note : Toutes les fonctions de cette structure sont sûres pour les threads.

Types publics

Fonctions publiques

bool exists() const
bool isDestroyed() const
operator QGlobalStatic<Holder>::Type *()
QGlobalStatic<Holder>::Type &operator*()
QGlobalStatic<Holder>::Type *operator->()

Macros

Q_GLOBAL_STATIC(Type, variableName, ...)

Description détaillée

La classe QGlobalStatic est l'API frontale exportée lorsque Q_GLOBAL_STATIC() est utilisé. Voir la documentation de la macro pour une discussion sur ses exigences et quand l'utiliser.

Normalement, vous n'utiliserez jamais cette classe directement, mais plutôt la macro Q_GLOBAL_STATIC(), comme suit :

Q_GLOBAL_STATIC(MyType, myGlobal)

L'exemple ci-dessus crée un objet de type QGlobalStatic appelé myGlobal. Après la déclaration ci-dessus, l'objet myGlobal peut être utilisé comme s'il s'agissait d'un pointeur sur un objet de type MyType, dont l'initialisation est garantie une seule fois. Outre l'utilisation en tant que pointeur, l'objet propose deux méthodes pour déterminer l'état actuel du global : exists() et isDestroyed().

Voir également Q_GLOBAL_STATIC().

Documentation sur les types de membres

[alias] QGlobalStatic::Type

Ce type est équivalent au paramètre Type transmis aux macros Q_GLOBAL_STATIC() ou Q_GLOBAL_STATIC_WITH_ARGS(). Il est utilisé dans les types de retour de certaines fonctions.

Documentation des fonctions membres

[noexcept] bool QGlobalStatic::exists() const

Cette fonction renvoie true si l'objet statique global a déjà terminé son initialisation (c'est-à-dire si le constructeur du type est déjà revenu) et n'a pas encore terminé sa destruction. Notez en particulier que cette fonction renvoie false si l'initialisation est toujours en cours.

Une fois que cette fonction a retourné true une fois, elle ne retournera plus jamais false jusqu'à ce que l'objet statique global soit détruit. Cette dernière se produit à la sortie du programme ou lorsque le plugin ou la bibliothèque contenant l'objet statique global est déchargé.

Cette fonction peut être appelée en toute sécurité à n'importe quel moment de l'exécution du programme : elle ne peut pas échouer et ne peut pas provoquer de blocage. En outre, elle n'entraînera pas la création du contenu s'il n'a pas encore été créé.

Cette fonction est utile si l'on peut déterminer les conditions initiales de l'objet statique global et que l'on préfère éviter une opération de construction éventuellement coûteuse.

Par exemple, dans l'exemple de code suivant, cette fonction est utilisée pour court-circuiter la création de l'objet statique global appelé globalState et renvoie une valeur par défaut :

Q_GLOBAL_STATIC(MyType, globalState)
QString someState()
{
    if (globalState.exists())
        return globalState->someState;
    return QString();
}

Avis sur la sécurité des threads : cette fonction est sûre dans le sens où elle peut être appelée par n'importe quel thread à n'importe quel moment et renverra toujours une réponse valide. Cependant, en raison de la nature non atomique de la construction, cette fonction peut renvoyer une valeur fausse pendant une courte période après la fin de la construction.

Remarque concernant l'ordre de la mémoire : cette fonction n'impose aucune garantie concernant l'ordre de la mémoire. Cette garantie est fournie par les fonctions d'accès qui renvoient le pointeur ou la référence au contenu. Si vous contournez les fonctions d'accès et tentez d'accéder à un état global défini par le constructeur, assurez-vous d'utiliser la sémantique d'ordonnancement de la mémoire correcte fournie par QAtomicInt ou QAtomicPointer.

Voir également isDestroyed().

[noexcept] bool QGlobalStatic::isDestroyed() const

Cette fonction renvoie true si l'objet statique global a déjà été détruit (c'est-à-dire si le destructeur du type est déjà revenu). En particulier, notez que cette fonction renvoie false si la destruction est toujours en cours.

Une fois que cette fonction a renvoyé true une fois, elle ne renverra plus jamais false jusqu'à ce que le programme soit redémarré ou que le plugin ou la bibliothèque contenant l'objet statique global soit déchargé et rechargé.

Cette fonction peut être appelée en toute sécurité à n'importe quel moment de l'exécution du programme : elle ne peut pas échouer et ne peut pas provoquer de blocage. En outre, elle n'entraînera pas la création du contenu s'il n'a pas encore été créé.

Cette fonction est utile dans le code susceptible d'être exécuté à l'arrêt du programme, afin de déterminer si le contenu est encore accessible ou non.

Voir également exists().

QGlobalStatic::operator QGlobalStatic<Holder>::Type *()

Cette fonction renvoie l'adresse du contenu de cette statique globale. Si le contenu n'a pas encore été créé, il sera créé à l'abri des threads par cette fonction. Si le contenu a déjà été détruit, cette fonction renvoie un pointeur nul.

Cette fonction peut être utilisée, par exemple, pour stocker le pointeur sur le contenu de la statique globale dans une variable locale, évitant ainsi de multiples appels à la fonction. L'implémentation de Q_GLOBAL_STATIC() est déjà assez efficace, mais dans les sections critiques en termes de performances, il peut être utile d'aider un peu le compilateur. A titre d'exemple :

Q_GLOBAL_STATIC(MyType, globalState)
QString someState()
{
    if (globalState::isDestroyed())
        return QString();
    MyType *state = globalState;
    if (state->condition)
        return state->value;
    else
        return state->worth;
}

Voir aussi operator->() et operator*().

QGlobalStatic<Holder>::Type &QGlobalStatic::operator*()

Cette fonction renvoie une référence au contenu de cette statique globale. Si le contenu n'a pas encore été créé, il sera créé à l'abri des threads par cette fonction.

Cette fonction ne vérifie pas si le contenu a déjà été détruit. Si cette fonction est appelée après la destruction de l'objet, elle renvoie une référence invalide qui ne doit pas être utilisée.

Voir aussi exists() et isDestroyed().

QGlobalStatic<Holder>::Type *QGlobalStatic::operator->()

Cette fonction renvoie l'adresse du contenu de cette statique globale. Si le contenu n'a pas encore été créé, il sera créé à l'abri des threads par cette fonction.

Cette fonction ne vérifie pas si le contenu a déjà été détruit et ne renvoie jamais null. Si cette fonction est appelée après la destruction de l'objet, elle renvoie un pointeur suspendu qui ne doit pas être déréférencé.

Voir également exists() et isDestroyed().

Documentation sur les macros

Q_GLOBAL_STATIC(Type, variableName, ...)

Crée un objet global et statique de type QGlobalStatic, nommé variableName. Il se comporte comme un pointeur sur Type. L'objet créé par Q_GLOBAL_STATIC s'initialise lors de sa première utilisation, ce qui signifie qu'il n'augmentera pas le temps de chargement de l'application ou de la bibliothèque. De plus, l'objet est initialisé de manière sûre pour les threads sur toutes les plates-formes.

Depuis Qt XML 6.3, cette macro admet des arguments variables, qui sont utilisés pour initialiser l'objet, ce qui rend inutile l'utilisation de Q_GLOBAL_STATIC_WITH_ARGS. Veuillez noter que les arguments ne nécessitent pas de parenthèses supplémentaires, contrairement à l'ancienne macro.

L'utilisation typique de cette macro est la suivante, dans un contexte global (c'est-à-dire pas dans le corps d'une fonction ou d'une classe) :

Q_GLOBAL_STATIC(MyType, myGlobal)

Cette macro est destinée à remplacer les objets statiques globaux qui ne sont pas POD (Plain Old Data, ou en termes de C++11, qui ne sont pas d'un type trivial), d'où son nom. Par exemple, le code C++ suivant crée un objet statique global :

static MyType myGlobal;

Par rapport à Q_GLOBAL_STATIC, et en supposant que MyType est une classe ou une structure qui a un constructeur, un destructeur, ou qui est autrement non POD, cette dernière a les inconvénients suivants :

  • elle nécessite l'initialisation de myGlobal au moment du chargement (c'est-à-dire que le constructeur par défaut de MyType est appelé lorsque la bibliothèque ou l'application est chargée) ;
  • l'objet sera initialisé même s'il n'est jamais utilisé ;
  • l'ordre d'initialisation et de destruction entre les différentes unités de traduction n'est pas déterminé, ce qui entraîne des utilisations possibles, avant l'initialisation ou après la destruction, par les constructeurs ou les destructeurs d'autres variables globales.

La macro Q_GLOBAL_STATIC résout tous ces problèmes en garantissant une initialisation à l'abri des threads lors de la première utilisation et en permettant à l'utilisateur de demander si le type a déjà été détruit, afin d'éviter le problème de l'utilisation après destruction (voir QGlobalStatic::isDestroyed()).

Constructeur et destructeur

Pour Q_GLOBAL_STATIC, si l'on ne dispose que d'un type et d'un nom de variable, son site Type doit être publiquement constructible par défaut et publiquement destructible. Sinon, Type doit avoir un constructeur public qui accepte les autres arguments de la macro. Pour Q_GLOBAL_STATIC_WITH_ARGS(), il doit y avoir un constructeur public qui accepte le troisième argument de la macro comme liste de paramètres.

Il n'est pas possible d'utiliser Q_GLOBAL_STATIC avec une macro Type dont le constructeur ou le destructeur est protégé ou privé. Si le type en question déclare ces membres protégés, il est possible de résoudre le problème en dérivant du type et en créant un constructeur et un destructeur publics. Si le type les déclare privés, une déclaration d'ami est nécessaire avant de dériver.

Par exemple, ce qui suit suffit pour créer MyType à partir d'un type MyOtherType défini précédemment, qui possède un constructeur par défaut protégé et/ou un destructeur protégé (ou qui les déclare privés, mais qui déclare également MyType comme ami).

class MyType : public MyOtherType { };
Q_GLOBAL_STATIC(MyType, myGlobal)

Aucun corps pour MyType n'est requis puisque le destructeur est un membre implicite, tout comme le constructeur par défaut si aucun autre constructeur n'est défini. Pour une utilisation avec des arguments après Type et variableName, ou avec Q_GLOBAL_STATIC_WITH_ARGS(), cependant, un corps de constructeur approprié est nécessaire :

class MyType : public MyOtherType
{
public:
    MyType(int i) : MyOtherType(i) {}
};
Q_GLOBAL_STATIC(MyType, myGlobal, 42)

Alternativement (depuis que C++11 a introduit l'héritage des constructeurs), on pourrait écrire :

class MyType : public MyOtherType
{
public:
    using MyOtherType::MyOtherType;
};
Q_GLOBAL_STATIC_WITH_ARGS(MyType, myGlobal, (42))

Placement

La macro Q_GLOBAL_STATIC crée un type, et une variable de ce type qui est nécessairement statique, à l'échelle globale. Il n'est pas possible de placer la macro Q_GLOBAL_STATIC à l'intérieur d'une fonction ou du corps d'une classe (cela entraînerait des erreurs de compilation).

Plus important encore, cette macro doit être placée dans les fichiers sources, jamais dans les en-têtes. Étant donné que l'objet résultant a un lien statique, si la macro est placée dans un en-tête et incluse dans plusieurs fichiers source, l'objet sera défini plusieurs fois et ne provoquera pas d'erreurs d'édition de liens. En revanche, chaque unité de traduction fera référence à un objet différent, ce qui peut entraîner des erreurs subtiles et difficiles à détecter.

Notez que la macro n'est pas recommandée pour les types qui sont POD ou qui ont des constructeurs constexpr C++11 (trivialement constructible et destructible). Pour ces types, il est toujours recommandé d'utiliser la statique normale, qu'elle soit globale ou locale à la fonction.

Cette macro fonctionnera, mais elle ajoutera une surcharge inutile.

Réentrance, sécurité des threads, blocages et sécurité des exceptions lors de la construction

La macro Q_GLOBAL_STATIC crée un objet qui s'initialise lors de la première utilisation de manière thread-safe : si plusieurs threads tentent d'initialiser l'objet en même temps, seul un thread procédera à l'initialisation, tandis que tous les autres threads attendront la fin du processus.

Si le processus d'initialisation génère une exception, l'initialisation est considérée comme incomplète et sera à nouveau tentée lorsque le contrôle atteindra une utilisation quelconque de l'objet. S'il existe des threads en attente d'initialisation, l'un d'entre eux sera réveillé pour tenter d'initialiser l'objet.

La macro ne garantit pas la réentrance à partir du même thread. Si l'on accède à l'objet statique global directement ou indirectement à partir de son propre constructeur, un blocage se produira certainement.

En outre, si deux objets Q_GLOBAL_STATIC sont initialisés sur deux threads différents et que la séquence d'initialisation de chacun d'eux accède à l'autre, un blocage peut se produire. Pour cette raison, il est recommandé de garder les constructeurs statiques globaux simples ou, à défaut, de s'assurer qu'il n'y a pas de dépendance croisée entre les utilisations statiques globales pendant la construction.

Destruction

Si l'objet n'est jamais utilisé pendant la durée de vie du programme, en dehors des fonctions QGlobalStatic::exists() et QGlobalStatic::isDestroyed(), le contenu du type Type ne sera pas créé et il n'y aura pas d'opération de sortie.

Si l'objet est créé, il sera détruit au moment de la sortie, de la même manière que la fonction C atexit(). Sur la plupart des systèmes, en fait, le destructeur sera également appelé si la bibliothèque ou le plugin est déchargé de la mémoire avant la sortie.

Comme la destruction est censée se produire à la sortie du programme, aucune sécurité thread n'est prévue. Cela vaut également pour le cas du déchargement d'un plugin ou d'une bibliothèque. De plus, comme les destructeurs ne sont pas censés lancer d'exceptions, aucune sécurité d'exception n'est fournie non plus.

Cependant, la réentrance est autorisée : pendant la destruction, il est possible d'accéder à l'objet statique global et le pointeur renvoyé sera le même qu'avant le début de la destruction. Une fois la destruction terminée, l'accès à l'objet statique global n'est pas autorisé, sauf comme indiqué dans l'API QGlobalStatic.

Voir également Q_APPLICATION_STATIC() et QGlobalStatic.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.