QGlobalStatic Struct
template <typename Holder> struct QGlobalStaticQGlobalStatic クラスは、グローバルな静的オブジェクトを実装するために使用されます。詳細...
| ヘッダー: | #include <QGlobalStatic> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
| qmake: | QT += core |
注:この構造体内のすべての関数はスレッドセーフです。
パブリック型
パブリック関数
| bool | exists() const |
| bool | isDestroyed() const |
| operator QGlobalStatic<Holder>::Type *() | |
| QGlobalStatic<Holder>::Type & | operator*() |
| QGlobalStatic<Holder>::Type * | operator->() |
マクロ
| Q_GLOBAL_STATIC(Type, variableName, ...) |
詳細な説明
QGlobalStatic<Holder> は、Holder がQ_GLOBAL_STATIC() マクロによって生成される内部型であるテンプレートクラスです。グローバル静的オブジェクトのユーザーから可視な型には、Type typedef を通じてアクセスできます。
QGlobalStatic クラスは、Q_GLOBAL_STATIC() が使用された際にエクスポートされるフロントエンド API です。その要件や使用時期については、マクロのドキュメントを参照してください。
通常、このクラスを直接使用することはなく、代わりに次のようにQ_GLOBAL_STATIC() マクロを使用します。
Q_GLOBAL_STATIC(MyType, myGlobal)上記の例は、myGlobal という名前の QGlobalStatic 型のオブジェクトを作成します。上記の宣言後、myGlobal オブジェクトは、MyType 型のオブジェクトへのポインタであるかのように使用でき、正確に 1 回だけ初期化されることが保証されています。ポインタとしての使用に加え、このオブジェクトには、グローバル変数の現在の状態を確認するための 2 つのメソッド、exists() およびisDestroyed() が用意されています。
Q_GLOBAL_STATIC()も参照してください 。
メンバ型のドキュメント
[alias] QGlobalStatic::Type
この型は、Q_GLOBAL_STATIC() または Q_GLOBAL_STATIC_WITH_ARGS() マクロに渡されるType パラメータと同等です。一部の関数の戻り値の型として使用されます。
メンバ関数のドキュメント
[noexcept] bool QGlobalStatic::exists() const
この関数は、グローバル静的オブジェクトの初期化がすでに完了しており(つまり、その型のコンストラクタがすでに返値を返している)、かつ破棄がまだ完了していない場合、true を返します。特に、初期化がまだ進行中の場合は、この関数はfalse を返すことに注意してください。
この関数が一度でも true を返すと、グローバル静的オブジェクトが破棄されるまでは二度と false を返すことはありません。グローバル静的オブジェクトの破棄は、プログラムの終了時、またはそのオブジェクトを含むプラグインやライブラリがアンロードされた際に発生します。
この関数は、プログラムの実行中のどの時点でも安全に呼び出すことができます。失敗することはなく、デッドロックを引き起こすこともありません。さらに、内容がまだ作成されていない場合でも、その作成を引き起こすことはありません。
この関数は、グローバル静的オブジェクトの初期条件を特定でき、コストがかかる可能性のある生成操作を避けたい場合に役立ちます。
たとえば、次のコードサンプルでは、この関数を使用して、globalState というグローバル静的オブジェクトの生成をショートサーキットし、デフォルト値を返しています:
Q_GLOBAL_STATIC(MyType, globalState)
QString someState()
{
if (globalState.exists())
return globalState->someState;
return QString();
}スレッドセーフに関する注意:この関数は、どのスレッドからでもいつでも呼び出すことができ、常に有効な応答を返すという点でスレッドセーフです。ただし、生成処理は非アトミックであるため、生成が完了した直後、この関数が一時的に false を返す可能性があります。
メモリ順序に関する注意:この関数は、メモリ順序に関する保証を一切行いません。メモリ順序の保証は、内容へのポインタまたは参照を返すアクセサ関数によって提供されます。アクセサ関数をバイパスして、コンストラクタによって設定されたグローバル状態へのアクセスを試みる場合は、QAtomicInt またはQAtomicPointer が提供する正しいメモリ順序のセマンティクスを必ず使用してください。
isDestroyed()も参照してください 。
[noexcept] bool QGlobalStatic::isDestroyed() const
この関数は、グローバル静的オブジェクトの破棄がすでに完了している場合(つまり、その型のデストラクタがすでに戻り値を返している場合)、true を返します。特に、破棄がまだ進行中の場合は、この関数はfalse を返すことに注意してください。
この関数が一度でも true を返すと、プログラムが再起動されるか、グローバル静的オブジェクトを含むプラグインまたはライブラリがアンロードされて再ロードされるまで、二度と false を返すことはありません。
この関数は、プログラムの実行中のどの時点でも安全に呼び出すことができます。失敗することはなく、デッドロックを引き起こすこともありません。また、内容がまだ作成されていない場合でも、その作成を引き起こすことはありません。
この関数は、プログラムのシャットダウン時に実行される可能性のあるコードにおいて、その内容にまだアクセスできるかどうかを判断するのに役立ちます。
exists()も参照してください 。
QGlobalStatic::operator QGlobalStatic<Holder>::Type *()
この関数は、このグローバル静的変数の内容へのアドレスを返します。内容がまだ作成されていない場合、この関数によってスレッドセーフな方法で作成されます。内容がすでに破棄されている場合、この関数はNULLポインタを返します。
この関数は、例えば、グローバル静的変数の内容へのポインタをローカル変数に格納し、それによって関数の多重呼び出しを回避するために使用できます。Q_GLOBAL_STATIC() の実装はすでに非常に効率的ですが、パフォーマンスが重要なセクションでは、コンパイラを少し手助けすることが役立つ場合があります。例えば:
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;
}operator->() およびoperator*()も参照してください 。
QGlobalStatic<Holder>::Type &QGlobalStatic::operator*()
この関数は、このグローバル静的変数の内容への参照を返します。内容がまだ作成されていない場合、この関数によってスレッドセーフな方法で作成されます。
この関数は、その内容がすでに破棄されているかどうかを検証しません。オブジェクトが破棄された後にこの関数が呼び出された場合、無効な参照が返されるため、それを使用してはなりません。
exists() およびisDestroyed()も参照してください 。
QGlobalStatic<Holder>::Type *QGlobalStatic::operator->()
この関数は、このグローバル静的変数の内容へのアドレスを返します。内容がまだ作成されていない場合、この関数によってスレッドセーフな方法で作成されます。
この関数は、その内容がすでに破棄されているかどうかを検証せず、決して null を返すことはありません。オブジェクトが破棄された後にこの関数が呼び出された場合、参照してはならないダングリングポインタを返します。
exists() およびisDestroyed()も参照してください 。
マクロのドキュメント
Q_GLOBAL_STATIC(Type, variableName, ...)
QGlobalStatic 型のグローバルかつ静的なオブジェクトを、variableName という名前で作成します。これはType へのポインタとして動作します。Q_GLOBAL_STATICによって作成されたオブジェクトは、最初の使用時に自身を初期化するため、アプリケーションやライブラリのロード時間を増加させることはありません。さらに、このオブジェクトはすべてのプラットフォームにおいてスレッドセーフな方法で初期化されます。
Qt 6.3以降、このマクロは可変個数の引数を受け付けるようになりました。これらはオブジェクトの初期化に使用されるため、Q_GLOBAL_STATIC_WITH_ARGS は不要になりました。なお、以前のマクロとは異なり、引数の後に余分な括弧を付ける必要はありませんのでご注意ください。
このマクロの一般的な使用法は、グローバルなコンテキスト(つまり、関数やクラスの本体内ではない場所)で次のように記述することです:
Q_GLOBAL_STATIC(MyType, myGlobal)このマクロは、POD(Plain Old Data、C++11の用語では「自明な型」ではない)ではないグローバル静的オブジェクトを置き換えることを目的としており、その名もこれに由来しています。例えば、以下のC++コードはグローバル静的変数を生成します:
static MyType myGlobal;Q_GLOBAL_STATICと比較して、MyType がコンストラクタやデストラクタを持つクラスまたは構造体である、あるいはその他の理由でPODではないと仮定した場合、後者には以下の欠点があります:
myGlobalのロード時初期化が必要となる(つまり、ライブラリやアプリケーションがロードされる際に、MyTypeのデフォルトコンストラクタが呼び出される);- そのオブジェクトが一度も使用されない場合でも初期化されてしまいます;
- 異なる翻訳単位間の初期化および破棄の順序は保証されないため、初期化前や破棄後に、他のグローバル変数のコンストラクタやデストラクタによって誤って使用される可能性がある。
Q_GLOBAL_STATIC マクロは、初回使用時にスレッドセーフな初期化を保証し、ユーザーがその型がすでに破棄されているかどうかを照会できるようにすることで、これらの問題をすべて解決し、破棄後の使用(use-after-destruction)の問題を回避します(QGlobalStatic::isDestroyed() を参照)。
コンストラクタとデストラクタ
Q_GLOBAL_STATIC の場合、型と変数名のみが指定されたときは、そのType は、パブリックでデフォルトコンストラクタを持ち、パブリックでデストラクタを持つものでなければなりません。 そうでない場合、Type には、マクロの残りの引数を受け入れるパブリックなコンストラクタがなければなりません。Q_GLOBAL_STATIC_WITH_ARGS() の場合、マクロの 3 番目の引数をパラメータのリストとして受け入れるパブリックなコンストラクタが存在しなければなりません。
Type の関連するコンストラクタまたはデストラクタが protected または private に宣言されている場合、Q_GLOBAL_STATIC を使用することはできません。 当該の型でそれらのメンバーが protected として宣言されている場合、その型を派生させてパブリックなコンストラクタとデストラクタを作成することで、この問題を回避できます。その型でそれらが private として宣言されている場合は、派生させる前に friend 宣言を行う必要があります。
たとえば、保護されたデフォルトコンストラクタや保護されたデストラクタを持つ(あるいはそれらをprivateと宣言しているが、MyType をfriendとして宣言している)事前に定義されたMyOtherType に基づいてMyType を作成するには、以下で十分です。
class MyType : public MyOtherType { };
Q_GLOBAL_STATIC(MyType, myGlobal)MyType の本体は不要です。これは、デストラクタが暗黙のメンバであり、他のコンストラクタが定義されていない場合はデフォルトコンストラクタも同様に暗黙のメンバとなるためです。ただし、Type やvariableName の後に引数を指定して使用する場合、あるいはQ_GLOBAL_STATIC_WITH_ARGS()を使用する場合は、適切なコンストラクタ本体が必要です:
class MyType : public MyOtherType
{
public:
MyType(int i) : MyOtherType(i) {}
};
Q_GLOBAL_STATIC(MyType, myGlobal, 42)あるいは(C++11で継承コンストラクタが導入されたため)、次のように記述することも可能です:
class MyType : public MyOtherType
{
public:
using MyOtherType::MyOtherType;
};
Q_GLOBAL_STATIC_WITH_ARGS(MyType, myGlobal, (42))配置
Q_GLOBAL_STATIC マクロは、グローバルスコープにおいて、ある型およびその型で必ず静的となる変数を生成します。Q_GLOBAL_STATIC マクロを関数内やクラスの本体内に配置することはできません(そうするとコンパイルエラーが発生します)。
さらに重要な点として、このマクロはヘッダーファイルではなく、ソースファイルに配置する必要があります。 生成されるオブジェクトは静的リンクを持つため、このマクロをヘッダーに記述し、複数のソースファイルからそのヘッダーがインクルードされた場合、オブジェクトは複数回定義されますが、リンクエラーは発生しません。その代わり、各翻訳単位が異なるオブジェクトを参照することになり、これが微妙で追跡困難なエラーにつながる可能性があります。
推奨されない使用法
なお、このマクロは、POD である型や、C++11 の constexpr コンストラクタ(自明に生成・破棄可能なもの)を持つ型での使用は推奨されません。これらの型については、グローバルであれ関数ローカルであれ、通常の static を使用することが依然として推奨されます。
このマクロは動作しますが、不要なオーバーヘッドが生じます。
再入可能性、スレッドセーフ性、デッドロック、および生成時の例外安全性
Q_GLOBAL_STATIC マクロは、スレッドセーフな方法で最初の使用時に自己初期化を行うオブジェクトを作成します。複数のスレッドが同時にオブジェクトの初期化を試みた場合、1 つのスレッドのみが初期化を実行し、他のすべてのスレッドは完了を待ちます。
初期化処理で例外がスローされた場合、初期化は完了していないものとみなされ、オブジェクトの使用箇所に制御が到達した際に再試行されます。初期化を待機しているスレッドがある場合、そのうちの1つが呼び起こされ、初期化を試行します。
このマクロは、同一スレッドからの再入可能性については保証しません。グローバル静的オブジェクトが自身のコンストラクタ内から直接または間接的にアクセスされた場合、確実にデッドロックが発生します。
さらに、2つの異なるスレッドで2つのQ_GLOBAL_STATICオブジェクトが初期化され、それぞれの初期化シーケンスがもう一方にアクセスする場合、デッドロックが発生する可能性があります。 そのため、グローバル静的コンストラクタは単純なものにするか、それが不可能な場合は、構築中にグローバル静的変数の使用に相互依存関係が生じないよう確保することをお勧めします。
破棄
プログラムの実行期間中にオブジェクトが一度も使用されない場合、QGlobalStatic::exists() およびQGlobalStatic::isDestroyed() 関数を除き、Type 型のコンテンツは作成されず、終了時の操作も行われません。
オブジェクトが作成された場合、C のatexit() 関数と同様に、終了時に破棄されます。実際、ほとんどのシステムでは、終了前にライブラリやプラグインがメモリからアンロードされた場合でも、デストラクタが呼び出されます。
破棄はプログラムの終了時に実行されることを意図しているため、スレッドセーフは保証されません。これには、プラグインやライブラリがアンロードされる場合も含まれます。さらに、デストラクタは例外をスローしないことが想定されているため、例外セーフも保証されません。
ただし、再入は許可されています。破棄処理中は、グローバル静的オブジェクトにアクセスすることが可能であり、返されるポインタは破棄処理開始前と同じものになります。破棄処理が完了した後は、QGlobalStatic API で明記されている場合を除き、グローバル静的オブジェクトへのアクセスは許可されません。
Q_APPLICATION_STATIC() および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.