MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
QMLの基礎 - シングルトンのソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
QMLの基礎 - シングルトン
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == オブジェクト指向のプログラム言語のクラスのデザインパターンの1種である。<br> デザインパターンとは、オブジェクト指向の言語で使用される設計のパターンのことであり、設計時に直面する問題とその解決策を整理してまとめたものを指す。<br> <br> シングルトンは、クラスの設計方法の1つであり、クラスのインスタンスを2つ以上生成できないようにすることで、常に同一のインスタンスが参照されるデザインパターンとなる。<br> 例えば、インスタンスの状態を常に持つ場合やクラス端で共通のデータとしてアクセスする必要がある場合に使用される。<br> <br><br> == 前提条件 == QQmlEngineヘッダファイルをインクルードする必要がある。<br> また、qmakeを使用する場合は、変数QTにqmlを追加する必要がある。<br> <syntaxhighlight lang="c++"> // cppファイル #include <QQmlEngine> </syntaxhighlight> <br> # qmakeファイル QT += qml <br><br> == QML_SINGLETONマクロ == QMLにおいて、内包する型がシングルトンであることを宣言するには、<code>QObject</code>クラスを継承したクラスを記述して、<code>QML_SINGLETON</code>マクロを使用する。<br> <br> これは、そのクラスが<code>Q_OBJECT</code>マクロが記述されており、QMLで利用可能である場合(<code>QML_ELEMENT</code>マクロまたは<code>QML_NAMED_ELEMENT()</code>マクロを持つ場合)にのみ有効である。<br> <br> <u>Qt 5の場合</u>、デフォルトでは、各<code>QQmlEngine</code>クラスは、その型に最初にアクセスした時、その型のデフォルトコンストラクタを使用してシングルトンのインスタンスを生成する。<br> もし、デフォルトコンストラクタが存在しない場合は、シングルトンは初期状態ではアクセス不能になるため、<br> <code>qmlRegisterSingletonType</code>関数に特定のファクトリー関数を指定する、または、<br> <code>qmlRegisterSingletonInstance</code>関数に同じクラスで同じ型の名前空間とバージョンの特定のインスタンスを指定して呼び出すことにより、オーバーライドすることができる。<br> <br> <u>Qt 6の場合</u>、デフォルトでは、各<code>QQmlEngine</code>クラスは、その型に最初にアクセスした時、その型のデフォルトコンストラクタ、または、<br> 静的ファクトリー関数(<code>T *create(QQmlEngine*, QJSEngine*)</code>)のいずれかを使用して、シングルトンのインスタンスを生成しようとする。<br> もし、両方が存在して、かつ、アクセス可能な場合、デフォルトコンストラクタが優先される。<br> <br> デフォルトコンストラクタも静的ファクトリ関数も存在しない場合は、シングルトンはアクセス不能になることに注意する。<br> <br> デフォルトコンストラクタを持つクラスをシングルトンとして宣言する場合は、<code>QML_SINGLETON</code>マクロを記述するだけである。<br> <br> <syntaxhighlight lang="c++"> class MySingleton : public QObject { Q_OBJECT QML_ELEMENT QML_SINGLETON // Q_PROPERTY( ... ) public: // メンバ変数 / メンバ関数, Q_INVOKABLEメソッド等 }; </syntaxhighlight> <br> シングルトンクラスがデフォルトで構築不可であり修正可能な場合は、アクセス可能にするため、静的ファクトリー関数を追加する。<br> <syntaxhighlight lang="c++"> class MySingleton : public QObject { Q_OBJECT QML_ELEMENT QML_SINGLETON // Q_PROPERTY( ... ) public: static MySingleton *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine) { MySingleton *result = nullptr; // 何らかのカスタムコンストラクタやファクトリを用いてオブジェクトを生成する // QMLエンジンは、最終的にこのオブジェクトの所有権を取得および削除する return result; } // メンバ変数 / メンバ関数, Q_INVOKABLEメソッド等 }; </syntaxhighlight> <br> シングルトンクラスが変更不可で、デフォルトコンストラクタや静的ファクトリー関数が存在しない場合、QML_FOREIGNラッパーを使用して、静的ファクトリー関数を定義することが可能である。<br> <syntaxhighlight lang="c++"> struct SingletonForeign { Q_GADGET QML_FOREIGN(MySingleton) QML_SINGLETON QML_NAMED_ELEMENT(MySingleton) public: static MySingleton *create(QQmlEngine *, QJSEngine *engine) { MySingleton *result = nullptr; // 何らかのカスタムコンストラクタやファクトリを用いてインスタンスを生成する // QMLエンジンは、最終的にそのインスタンスの所有権を取得および削除する return result; } }; </syntaxhighlight> <br> もし、特定のシングルトンオブジェクトを提供する場合、その生成はコントロールできないが、静的ファクトリー関数からそれを返すことができる。<br> これは、<code>qmlRegisterSingletonInstance</code>関数の代わりとなるものである。 <syntaxhighlight lang="c++"> qmlRegisterSingletonInstance("MyModule", 1, 0, "MySingleton", myObject); </syntaxhighlight> <br> もし、上記のqmlRegisterSingletonInstance("MyModule", 1, 0, "MySingleton", myObject)を記述している場合、MyObjectがMySingleton *型であれば、<br> 代わりに、以下の例のようにクラスを定義することができる。<br> <br> これは、既存のクラスであるMySingletonクラスは、MySingletonというQMLのシングルトンであることが宣言される。<br> s_singletonInstanceメンバを設定することにより、使用する前にいつでもそのインスタンスを指定することができるため、MySingletonクラス自身を変更する必要はない。<br> <syntaxhighlight lang="c++"> struct SingletonForeign { Q_GADGET QML_FOREIGN(MySingleton) QML_SINGLETON QML_NAMED_ELEMENT(MySingleton) public: // Initialize this using myObject where you would previously // call qmlRegisterSingletonInstance(). inline static MySingleton *s_singletonInstance = nullptr; static MySingleton *create(QQmlEngine *, QJSEngine *engine) { // The instance has to exist before it is used. We cannot replace it. Q_ASSERT(s_singletonInstance); // The engine has to have the same thread affinity as the singleton. Q_ASSERT(engine->thread() == s_singletonInstance->thread()); // There can only be one engine accessing the singleton. if (s_engine) Q_ASSERT(engine == s_engine); else s_engine = engine; // Explicitly specify C++ ownership so that the engine doesn't delete // the instance. QJSEngine::setObjectOwnership(s_singletonInstance, QJSEngine::CppOwnership); return s_singletonInstance; } private: inline static QJSEngine *s_engine = nullptr; }; </syntaxhighlight> <br> <u>※注意</u><br> <u>このパターンは、シングルトンが複数のQMLエンジンからアクセスされる場合、または、アクセスするQMLエンジンがシングルトンオブジェクト自身と異なるスレッドアフィニティを持っている場合は動作しない。</u><br> <u>上記で示したように、<code>create()</code>メソッドのパラメータでエンジンのIDやスレッドアフィニティを確認することにより、アサーションすることができる。</u><br> <br><br> __FORCETOC__ [[カテゴリ:Qt]]
QMLの基礎 - シングルトン
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse