目次
2.1 強力なシグナルとスロットのメカニズム = 「シグナルを介したオブジェクト間の通信」
第1章;序章
Qt では、C++ が主なプログラミング言語として使用されます。C++ は、汎用の厳密に型指定されたプログラミング言語であり、Qt フレームワークと組み合わせて使用すると、クロスプラットフォームのグラフィカル ユーザー インターフェイス (GUI) アプリケーションやその他の種類のアプリケーションを簡単に構築できます。
Qt で C++ を使用する場合のいくつかの側面と機能を次に示します。
-
オブジェクト指向プログラミング (OOP): C++ はオブジェクト指向プログラミング言語であり、Qt はオブジェクト指向の方法で構築されています。C++ を使用すると、開発者はクラス、継承、ポリモーフィズムなどの OOP 概念を利用してコードを編成および管理できます。
-
Qt のクラスとライブラリ: Qt は、GUI 要素の作成、イベントの処理、グラフィックの描画、ネットワーク経由の通信などのためのクラスとライブラリの豊富なセットを提供します。これらのクラスとライブラリは C++ で記述されており、開発者はこれらを使用することで強力なアプリケーションを迅速に構築できます。
-
シグナルとスロットのメカニズム: Qt のシグナルとスロットのメカニズムは、C++ の特性を通じて実装されています。C++ の関数ポインターと演算子のオーバーロードを利用して、オブジェクト間の通信を柔軟かつ信頼性の高いものにします。
-
メモリ管理: Qt は RAII (リソース取得は初期化) メモリ管理テクノロジを使用し、オブジェクトのライフサイクル管理を自動化することでメモリ リークとリソース管理の複雑さを軽減します。同時に、Qt は開発者がメモリをより便利に管理できるようにするスマート ポインターやその他のメモリ管理ツールも提供します。
-
例外処理: C++ は例外処理メカニズムをサポートしており、Qt の多くのクラスと関数も例外を使用してエラーや異常な状態を処理します。開発者は、try-catch ブロックを使用して、これらの例外をキャッチして処理できます。
-
C++11 以降のサポート: Qt による C++11 標準以降のサポートは徐々に増加しています。開発者は、自動型推論、ラムダ式、スマート ポインターなどの C++11 の新機能を使用して、Qt アプリケーションをより簡単かつ便利に作成できます。
Qt は主なプログラミング言語として C++ を使用しますが、QML (Qt Quick) を使用した宣言型プログラミングなど、他のプログラミング言語もある程度サポートしていることに注意してください。QML を使用すると、開発者は JavaScript 言語を使用して Qt と対話し、動的で最新のユーザー インターフェイスを構築できます。
要約すると、Qt と C++ を組み合わせることで、開発者がクロスプラットフォーム、高性能、機能豊富なアプリケーションを構築できる強力な開発環境が提供されます。
第 2 章 言語の特徴
2.1 オブジェクト指向のカプセル化
int main(int argc, char *argv[])
{
QApplication a(argc, argv); //应用程序对象,管理UI主线程
QIcon icon(":/res/logo.png");
a.setWindowIcon(icon); //设置应用程序的icon
MainWindow w; //创建主窗口对象
w.show(); //展示主窗口
return a.exec(); //执行应用程序的事件处理线程
}
2.1 強力なシグナルとスロットのメカニズム = 「シグナルを介したオブジェクト間の通信」
シグナルとスロットの基本原理は、登録とコールバックのメカニズムです。!!
2.2 クエリ可能なデザインオブジェクトのプロパティ
2.3 時間とイベントのフィルター
2.4 文字列の国際化のサポート
2.5 時間の精度
洗練されたインターバル駆動のタイマーにより、イベント駆動の GUI にマルチタスクをエレガントに統合できます。
2.6. 適切なオブジェクト構成構造 = 「クラス継承」
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QFont>
class MyMainWindow : public QWidget // MyMainWindow继承承QWidget对象
{ public: MyMainWindow(); プライベート: QPushButton *b1; };
2.7 Qt はワイルド ポインターの問題を処理します
QPointer クラスを使用して、ポインターが指すオブジェクトが削除されたときにポインターを 0 に設定します。
2.8 柔軟な動的な型変換
Qt の C++ への拡張は、Qt のメタオブジェクト システムと呼ばれる QObject (Java の java.lang.Object に似ています) から始まります。これには、メタオブジェクト コンパイラ MOC のサポートが必要です。Qt は、C++ をカプセル化して拡張することにより、柔軟な GUI プログラミングを実装します。
2.9 コンストラクター
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
qDebug() << "main threadId: " << QThread::currentThreadId();
}
MainWindow::MainWindow(QWidget *parent)
{
}
MainWindows クラスのパラメーター化されたコンストラクター: MainWindow(QWidget *parent)
パラメータ:
- 親: 親ウィンドウオブジェクトを指します。
2.10 初期化リストとオブジェクトの初期化
このコードは、 Qtメイン ウィンドウ クラス MainWindow
のコンストラクターの典型的な実装です。行ごとの説明は次のとおりです。
class MainWindow : public QMainWindow //继承于QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
-
MainWindow::MainWindow(QWidget *parent)
これはコンストラクターの定義であり、MainWindow
クラスのコンストラクターを表し、 パラメーターQWidget*
のタイプを 受け取りますparent
。parent是构造函数的参数,用于指向父窗口。
-
: はコンストラクターの初期化子リストです。
-
: QMainWindow(parent)
QMainWindow
MainWindow クラスの基本クラスのコンストラクター を呼び出し、parent
それにパラメーターを渡すことを示します。これにより、MainWindow
オブジェクトが構築されるときに、その基本クラスも確実に構築されますQMainWindow成员
。 -
, ui(new Ui::MainWindow)
ui
という名前のUi::MainWindow
クラスへのポインター を初期化するメンバー変数/UI に慣れた初期化ステートメントです。 は、メイン ウィンドウの UI レイアウトと要素を管理する、Ui::MainWindow
自動的に生成されるクラスです。ui は MainWindow オブジェクト用です。
このコードの目的は、コンストラクターでメイン ウィンドウ オブジェクトを初期化し、 Ui::MainWindow
ユーザー インターフェイス関連のコンテンツを管理するためのオブジェクト ui を作成することです。通常、このコンストラクターでは、ウィンドウ タイトルの設定、コンポーネントの追加など、他の初期化操作も実行できます。
このコードは、Qt のビジュアル デザイン ツール (Qt Creator など) を使用して自動的に生成されることに注意してください。ビジュアル デザイン ツールでは、ユーザーはドラッグしてレイアウトすることでユーザー インターフェイスを作成でき、ツールはこのコンストラクターと関連コードを自動的に生成します。ユーザーは、生成されたコンストラクターにカスタム ロジックと処理コードを追加できます。
コンストラクターの初期化リストは、コンストラクターの定義内のコロン ():
以降の部分であり、メンバー変数を初期化し、基本クラスのコンストラクターを呼び出すために使用されます。
初期化子リストの構文はカンマで区切られたメンバー初期化ステートメントであり、各メンバー初期化ステートメントはメンバー名、括弧、および初期化値で構成されます。
一般的なコンストラクター初期化子リストの例は次のとおりです。
ClassName::ClassName(Type1 arg1, Type2 arg2)
: member1(arg1), member2(arg2), member3()
{
// 构造函数的其他代码
}
上の例では:
ClassName
クラスの名前を示します。Type1
および メンバー変数 sumType2
の型です 。member1
member2
arg1
と はarg2
コンストラクターのパラメーターです。member1(arg1)
および はmember2(arg2)
メンバー変数初期化ステートメントであり、パラメーターの値をメンバー変数に初期化するために使用されます。member3()
これはメンバー変数を初期化するもう 1 つの方法であり、パラメーターが指定されていない場合は、初期化にデフォルトのコンストラクターが使用されます。
コンストラクターの初期化リストの役割には次のものが含まれます。
-
メンバー変数の初期化: 初期化リストを使用すると、オブジェクトの作成時に初期値をメンバー変数に直接割り当てることができ、コンストラクター本体での再代入操作を回避できます。
-
基本クラス コンストラクターを呼び出す: 現在のクラスが派生クラスの場合、初期化リストを使用して基本クラス コンストラクターを呼び出し、基本クラスから継承されたメンバー変数が正しく初期化されていることを確認できます。
初期化リストを使用すると、コードの実行効率が向上し、オブジェクト状態の正しく一貫した初期化が保証されます。特に複雑なクラス コンストラクターの場合、初期化リストで複数のメンバー変数の値を一度に設定すると、コードがより明確になり読みやすくなります。
潜在的な問題を避けるために、初期化リスト内のメンバー変数の初期化順序は、クラス内で宣言された順序と一致している必要があることに注意してください。
派生クラスのコンストラクターでは、初期化リストを使用して基本クラスのコンストラクターを呼び出し、派生クラスのメンバー変数を初期化することもできます。初期化子リストの構文は、基本クラスのコンストラクターを呼び出す構文と似ています。
以下は、派生クラスのコンストラクター初期化子リストの例です。
DerivedClassName::DerivedClassName(Type1 arg1, Type2 arg2, Type3 arg3)
: BaseClassName(arg1), member1(arg2), member2(arg3)
{
// 派生类构造函数的其他代码
}
上の例では:
DerivedClassName
派生クラスの名前を示します。Type1
、Type2
および はType3
、基本クラスのコンストラクターと派生クラスのメンバー変数の型です。arg1
、arg2
およびはarg3
コンストラクターのパラメーターです。BaseClassName(arg1)
基本クラスのコンストラクターを呼び出し、それにパラメーターの値を渡すことです。member1(arg2)
および はmember2(arg3)
派生クラスのメンバー変数初期化ステートメントであり、パラメーターの値をメンバー変数に初期化するために使用されます。
初期化リストを使用すると、基本クラスと派生クラスのメンバー変数を派生クラスのコンストラクターで正しく初期化し、オブジェクトの完全な初期化を保証できます。さらに、派生クラスが独自のメンバー変数を定義していない場合は、基本クラスのコンストラクターを呼び出すだけで済みます。
派生クラスのコンストラクターは、基本クラスのデフォルト コンストラクターを自動的に呼び出すことに注意してください。基本クラスがデフォルト コンストラクターを提供しない場合、派生クラスのコンストラクターは、初期化リスト内の基本クラスの適切なコンストラクターを明示的に呼び出す必要があります。同時に、派生クラスのコンストラクターは、初期化リスト内の直接基本クラスのコンストラクターのみを呼び出すことができ、間接基本クラスのコンストラクターを呼び出すことはできません。
全体として、派生クラスの初期化リストは、派生クラス自体のメンバー変数を初期化し、基本クラスのコンストラクターを呼び出すために使用されます。初期化リストを使用すると、オブジェクトのさまざまな部分が派生クラスのコンストラクターで正しく初期化されていることを確認でき、オブジェクトが正しく作成および初期化されていることを確認できます。
2.11 override
C++ では、override
派生クラスの基本クラス仮想関数のオーバーライドを明示的に示すために使用されるキーワードです。
キーワードを使用して、派生クラスが基本クラスの仮想関数override
を正しくオーバーライドできるようにすることで、コードの可読性と保守性を向上させることができます。
使用される構文はoverride
次のとおりです。
class Base {
public:
virtual void myFunction();
};
class Derived : public Base {
public:
void myFunction() override; //头文件中声明,需要覆盖,在源文件中,需要定义实体函数
};
上の例では、Base
クラスは仮想関数を宣言していますmyFunction()
。派生クラスDerived
では、override
キーワードの使用は基本クラスの仮想関数のオーバーライドを明示的に示します。このように、基本クラスの仮想関数が派生クラスで正しくオーバーライドされない場合、コンパイラはエラーを報告します。
キーワードが派生クラスで使用される場合override
、コンパイラは関数のシグネチャが基本クラスの仮想関数のシグネチャと一致するかどうかをチェックします。署名が一致しない場合 (パラメーター リスト、戻り値の型が異なるなど)、コンパイラーはエラーを報告します。
キーワードを使用すると、override
より強力な型チェックが提供され、開発者が派生クラスの基本クラスの仮想関数を正しくオーバーライドできるようになります。偶発的な間違いやタイプミスによって引き起こされる仮想関数カバレッジの失敗を防ぎます。
override
このキーワードは、基本クラスの仮想関数のオーバーライドにのみ適用され、非仮想関数または静的関数のオーバーライドには適用されないことに注意してください。非仮想関数または静的関数をオーバーライドする場合、override
キーワードを使用する必要はありません。
キーワードを使用するとoverride
、コードの信頼性と保守性が向上し、開発者がよくある間違いを回避し、プログラムの動作をより予測しやすくすることができます。