📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

 
(同じ利用者による、間の2版が非表示)
200行目: 200行目:
<u>後方互換性のためにサポートされている。</u><br>
<u>後方互換性のためにサポートされている。</u><br>
<br>
<br>
==== Q_DISABLE_COPY / Q_DISABLE_MOVE ====
<code>Q_DISABLE_COPY</code>マクロは、クラスのコピーコンストラクタとコピー代入演算子を削除する。<br>
これにより、クラスのインスタンスが誤ってコピーされることを防ぐ。<br>
<br>
<code>Q_DISABLE_MOVE</code>マクロは、クラスのムーブコンストラクタとムーブ代入演算子を削除する。<br>
これにより、クラスのインスタンスが移動されることを防ぐ。<br>
<br>
これらのマクロは、以下に示すようなメリットがある。<br>
* オブジェクトの意図しない複製や移動を防ぐことができる。
* リソースの所有権に関する問題を回避できる。
* クラスの設計意図を明確に示すことができる。
<br>
以下の例では、クラスのインスタンスがコピーや移動されることを防ぐ方法を示している。<br>
これにより、意図しないオブジェクトの複製や移動を防ぎ、リソース管理を適切に行うことができる。<br>
<br>
<syntaxhighlight lang="c++">
// NonCopyable.hファイル
class NonCopyable
{
private:
    Q_DISABLE_COPY(NonCopyable)
public:
    NonCopyable()  = default;
    ~NonCopyable() = default;
    void doSomething() { qDebug() << "Doing something"; }
};
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
// NonMovable.hファイル
class NonMovable
{
private:
    Q_DISABLE_MOVE(NonMovable)
public:
    NonMovable()  = default;
    ~NonMovable() = default;
    void doSomething() { qDebug() << "Doing something"; }
};
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
// 使用例
#include "NonCopyable.h"
#include "NonMovable.h"
void testNonCopyable()
{
    NonCopyable nc1;
    // NonCopyable nc2 = nc1;  // コンパイルエラー: コピーコンストラクタは削除されている
    // NonCopyable nc3(nc1);  // コンパイルエラー: コピーコンストラクタは削除されている
    // nc1 = NonCopyable();    // コンパイルエラー: コピー代入演算子は削除されている
    nc1.doSomething();        // コンパイル可能
}
void testNonMovable()
{
    NonMovable nm1;
    // NonMovable nm2 = std::move(nm1);  // コンパイルエラー: ムーブコンストラクタは削除されている
    // nm1 = NonMovable();              // コンパイルエラー: ムーブ代入演算子は削除されている
    nm1.doSomething();                  // コンパイル可能
}
int main()
{
    testNonCopyable();
    testNonMovable();
    return 0;
}
</syntaxhighlight>
<br>
==== Q_FLAG / Q_FLAGS ====
==== Q_FLAG / Q_FLAGS ====
列挙型をQtのメタオブジェクトシステムに登録するために使用する。<br>
列挙型をQtのメタオブジェクトシステムに登録するために使用する。<br>
537行目: 621行目:
     qDebug() << data2.value();  // 出力: 100
     qDebug() << data2.value();  // 出力: 100
  }
  }
</syntaxhighlight>
<br>
==== Q_D / Q_Q ====
d-pointerイディオムの実装時において、privateクラスとpublicクラス間のアクセスを容易にする。<br>
<br>
Q_Dマクロは、publicクラスからprivateクラスにアクセスするために使用する。<br>
Q_Qマクロは、privateクラスからpublicクラスにアクセスするために使用する。<br>
<br>
これらのマクロを使用することにより、以下に示すようなメリットがある。<br>
* private実装とpublicインターフェース間のアクセスを簡潔に記述することができる。
* タイプセーフなアクセスが可能になる。
* ソースコードの可読性が向上する。
<br>
以下の例では、publicクラスとprivateクラス間で相互にアクセスする方法を示している。<br>
これにより、実装の詳細を隠蔽しつつ、必要な場合に内部データにアクセスすることができる。<br>
<syntaxhighlight lang="c++">
// MyClass.hファイル
#include "MyClassPrivate.h"
class MyClassPrivate;
class MyClass
{
private:
    Q_DECLARE_PRIVATE(MyClass)
    MyClassPrivate *d_ptr;
public:
    MyClass() : d_ptr(new MyClassPrivate(this)) {}
    ~MyClass()
    {
      delete d_ptr;
    }
    void publicMethod()
    {
      Q_D(MyClass);  // d は MyClassPrivate* 型
      d->privateMethod();
      qDebug() << "Public method called, someData:" << d->someData;
    }
};
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
// MyClassPrivate.hファイル
class MyClassPrivate
{
public:
    MyClassPrivate(MyClass *q) : q_ptr(q) {}
    void privateMethod()
    {
      Q_Q(MyClass);  // qはMyClass*型
      someData = 42;
      qDebug() << "Private method called by" << q;
    }
    MyClass *q_ptr;
    Q_DECLARE_PUBLIC(MyClass)
    int someData;
};
  </syntaxhighlight>
  </syntaxhighlight>
<br><br>
<br><br>