QGlobalStatic Struct
template <typename Holder> struct QGlobalStaticLa classe QGlobalStatic sert à implémenter un objet statique global. En savoir plus...
| En-tête : | #include <QGlobalStatic> |
| CMake : | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
| qmake : | QT += core |
Remarque : toutes les fonctions de cette structure sont thread-safe.
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
QGlobalStatic<Holder> est une classe de modèle où Holder est un type interne généré par la macro Q_GLOBAL_STATIC(). Le type visible par l'utilisateur de l'objet statique global est accessible via le typedef Type.
La classe QGlobalStatic constitue l’API frontale exportée lorsque Q_GLOBAL_STATIC() est utilisée. Reportez-vous à la documentation de la macro pour en savoir plus sur ses exigences et sur les cas d’utilisation.
En règle générale, vous n’utiliserez jamais cette classe directement, mais vous utiliserez 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 nommé myGlobal. Après la déclaration ci-dessus, l'objet myGlobal peut être utilisé comme s'il s'agissait d'un pointeur vers un objet de type MyType, dont l'initialisation est garantie une seule fois. Outre son utilisation en tant que pointeur, l'objet propose deux méthodes permettant de déterminer l'état actuel de la variable globale : exists() et isDestroyed().
Voir également Q_GLOBAL_STATIC().
Documentation sur les types 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 sur les 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 a déjà renvoyé une valeur) 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 renvoyé `true` une première fois, elle ne renverra plus jamais `false` jusqu’à ce que l’objet statique global soit détruit. Cela se produit à la sortie du programme ou lorsque le plugin ou la bibliothèque contenant l’objet statique global est déchargé(e).
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. De plus, elle n’entraînera pas la création du contenu si celui-ci 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 potentiellement coûteuse.
Par exemple, dans l’extrait de code suivant, cette fonction est utilisée pour court-circuiter la création de l’objet statique global nommé « globalState » et renvoie une valeur par défaut :
Q_GLOBAL_STATIC(MyType, globalState)
QString someState()
{
if (globalState.exists())
return globalState->someState;
return QString();
}Remarque concernant la sécurité inter-threads : cette fonction est sûre inter-threads dans la mesure où elle peut être appelée depuis n’importe quel thread à tout moment et renverra toujours une réponse valide. Cependant, en raison de la nature non atomique de la construction, cette fonction peut renvoyer « false » pendant un court instant après la fin de la construction.
Remarque sur l’ordre de mémoire : cette fonction n’impose aucune garantie quant à l’ordre de mémoire. Celui-ci est assuré 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, veillez à utiliser la sémantique d’ordre de mémoire appropriée fournie par QAtomicInt ou QAtomicPointer.
Voir également isDestroyed().
[noexcept] bool QGlobalStatic::isDestroyed() const
Cette fonction renvoie « true » si la destruction de l'objet statique global est déjà terminée (c'est-à-dire si le destructeur du type a déjà renvoyé une valeur). Notez notamment que cette fonction renvoie « false » si la destruction est toujours en cours.
Une fois que cette fonction a renvoyé « true » une première fois, elle ne renverra plus jamais « false » tant que le programme n’aura pas été redémarré ou que le plugin ou la bibliothèque contenant l’objet statique global n’aura pas été déchargé puis 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. De plus, elle n’entraînera pas la création du contenu si celui-ci n’a pas encore été créé.
Cette fonction est utile dans le code susceptible d’être exécuté lors de 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 variable statique globale. Si le contenu n'a pas encore été créé, il sera créé par cette fonction de manière sécurisée pour les threads. Si le contenu a déjà été détruit, cette fonction renverra un pointeur nul.
Cette fonction peut être utilisée, par exemple, pour stocker le pointeur vers le contenu de la variable 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 où les performances sont critiques, il peut être utile d’aider un peu le compilateur. Par 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 également ` operator->()` et ` operator*()`.
QGlobalStatic<Holder>::Type &QGlobalStatic::operator*()
Cette fonction renvoie une référence au contenu de cette variable statique globale. Si ce contenu n'a pas encore été créé, il le sera par cette fonction de manière sécurisée pour les threads.
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 renverra une référence non valide qui ne doit pas être utilisée.
Voir également exists() et isDestroyed().
QGlobalStatic<Holder>::Type *QGlobalStatic::operator->()
Cette fonction renvoie l'adresse du contenu de cette variable statique globale. Si le contenu n'a pas encore été créé, il sera créé par cette fonction de manière sécurisée pour les threads.
Cette fonction ne vérifie pas si le contenu a déjà été détruit et ne renvoie jamais la valeur 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 vers ` 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 plateformes.
Depuis Qt 6.3, cette macro admet des arguments variadiques, qui sont utilisés pour initialiser l’objet, rendant ainsi 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 en dehors de toute fonction ou du corps d'une classe) :
Q_GLOBAL_STATIC(MyType, myGlobal)Cette macro est destinée à remplacer les objets statiques globaux qui ne sont pas de type POD (Plain Old Data, ou, selon la terminologie C++11, qui ne sont pas de 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 qu’ MyType soit une classe ou une structure dotée d’un constructeur, d’un destructeur ou qui soit autrement non-POD, cette dernière présente les inconvénients suivants :
- elle nécessite l’initialisation à la charge d’
myGlobal(c’est-à-dire que le constructeur par défaut d’MyTypeest appelé lors du chargement de la bibliothèque ou de l’application) ; - 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 peut entraîner des utilisations, 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 sans risque de conflit entre threads lors de la première utilisation et en permettant à l’utilisateur de vérifier si le type a déjà été détruit, afin d’éviter le problème d’utilisation après destruction (voir QGlobalStatic::isDestroyed()).
Constructeur et destructeur
Pour Q_GLOBAL_STATIC, lorsqu’on ne lui fournit qu’un type et un nom de variable, son Type doit pouvoir être instancié par défaut et détruit publiquement. Sinon, l’ Type doit disposer d’un constructeur public acceptant les arguments restants de la macro. Pour Q_GLOBAL_STATIC_WITH_ARGS(), il doit exister un constructeur public acceptant le troisième argument de la macro comme liste de paramètres.
Il n’est pas possible d’utiliser Q_GLOBAL_STATIC avec un type Type dont le constructeur ou le destructeur concerné est protégé ou privé. Si le type en question déclare ces membres comme « protected », il est possible de contourner le problème en dérivant de ce type et en créant un constructeur et un destructeur publics. Si le type les déclare comme « private », une déclaration « friend » est nécessaire avant de dériver.
Par exemple, le code suivant suffit pour créer un ` MyType ` basé sur un ` MyOtherType ` préalablement défini qui possède un constructeur par défaut protégé et/ou un destructeur protégé (ou qui les déclare privés, mais déclare également ` MyType ` comme ami).
class MyType : public MyOtherType { };
Q_GLOBAL_STATIC(MyType, myGlobal)Aucun corps n’est requis pour MyType, car le destructeur est un membre implicite, tout comme le constructeur par défaut si aucun autre constructeur n’est défini. Toutefois, pour une utilisation avec des arguments après Type et variableName, ou avec Q_GLOBAL_STATIC_WITH_ARGS(), un corps de constructeur adapté est nécessaire :
class MyType : public MyOtherType
{
public:
MyType(int i) : MyOtherType(i) {}
};
Q_GLOBAL_STATIC(MyType, myGlobal, 42)Sinon (puisque C++11 a introduit les constructeurs hérités), on pourrait écrire :
class MyType : public MyOtherType
{
public:
using MyOtherType::MyOtherType;
};
Q_GLOBAL_STATIC_WITH_ARGS(MyType, myGlobal, (42))Emplacement
La macro Q_GLOBAL_STATIC crée un type, ainsi qu’une variable de ce type qui est nécessairement statique, dans la portée 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 des fichiers source, jamais dans des en-têtes. L’objet résultant ayant une liaison statique, si la macro est placée dans un en-tête et incluse par plusieurs fichiers source, l’objet sera défini plusieurs fois sans provoquer d’erreurs de liaison. En revanche, chaque unité de traduction fera référence à un objet différent, ce qui pourrait entraîner des erreurs subtiles et difficiles à détecter.
Utilisations non recommandées
Notez que l’utilisation de cette macro n’est pas recommandée avec des types qui sont des POD ou qui possèdent des constructeurs constexpr C++11 (trivialement constructibles et destructibles). Pour ces types, il est toujours recommandé d’utiliser la déclaration « static » classique, qu’elle soit globale ou locale à une fonction.
Cette macro fonctionnera, mais elle ajoutera une surcharge inutile.
Réentrance, sécurité des threads, blocages et sécurité face aux exceptions lors de la construction
La macro Q_GLOBAL_STATIC crée un objet qui s’initialise de manière sécurisée vis-à-vis des threads lors de sa première utilisation : si plusieurs threads tentent d’initialiser l’objet en même temps, un seul thread procédera à l’initialisation, tandis que tous les autres threads attendront que celle-ci soit terminée.
Si le processus d’initialisation lève une exception, l’initialisation est considérée comme incomplète et sera réessayée lorsque le contrôle atteindra une utilisation quelconque de l’objet. S’il y a des threads en attente de l’initialisation, l’un d’entre eux sera réveillé pour tenter l’initialisation.
La macro n’offre aucune garantie quant à la réentrance à partir du même thread. Si l’objet statique global est accédé directement ou indirectement depuis l’intérieur de son propre constructeur, un blocage (deadlock) se produira inévitablement.
De plus, si deux objets `Q_GLOBAL_STATIC` sont initialisés sur deux threads différents et que la séquence d’initialisation de chacun accède à l’autre, un blocage (deadlock) peut se produire. C’est pourquoi il est recommandé de veiller à ce que les constructeurs d’objets statiques globaux restent simples ou, à défaut, de s’assurer qu’il n’y a pas de dépendance croisée entre les utilisations de ces objets statiques globaux lors de leur 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 de type ` Type ` ne sera pas créé et aucune opération ne sera effectuée au moment de la sortie.
Si l’objet est créé, il sera détruit à la sortie, à l’instar de la fonction C ` atexit() `. Sur la plupart des systèmes, en effet, le destructeur sera également appelé si la bibliothèque ou le plugin est déchargé de la mémoire avant la sortie.
La destruction étant prévue à la sortie du programme, aucune sécurité des threads n’est assurée. Cela inclut le cas du déchargement d’un plugin ou d’une bibliothèque. De plus, les destructeurs n’étant pas censés lever d’exceptions, aucune sécurité face aux exceptions n’est non plus assurée.
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 plus autorisé, sauf indication contraire 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.