C++ 入門指南

單元 25 - 專案的檔案組成

本書已有新版,請參考 C++ 入門指南 4.01 - 單元 26 - MVC 模式與 QML

以 MVC 模式來看我們發展的專案 (project) , M 是指 Encrypt 類別 (class) ,也就是我們已經開發好的 encrypt.cpp , V 為 Qt Creator 自動產生的 encryptwindow.ui , C 則是 encryptwindow.cpp

Model → encrypt.cpp
View → encryptwindow.ui
Controller → encryptwindow.cpp

單元 29 才會開始整合 Encrypt 類別,我們在這個單元內先來看看 Qt Creator 自動產生的幾個檔案,下圖為新增完成的 encrypt_gui 專案資料夾

-encrypt_gui-

副檔名 encrpt_gui.proencrpt_gui.pro.user 是專案檔案, encryptwindow.ui 則是 GUI 介面檔案,其他還有三個程式檔案, encryptwindow.hencryptwindow.cpp 的標頭檔 (header file) ,這是 EncryptWindow 類別的實作檔案,作為控制 GUI 元件之用,而 main.cpp 則是包含 main() 函數的執行程式,我們先來看看 main() 的內容囉

#include "encryptwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    EncryptWindow w;
    w.show();
    return a.exec();
}

我們採淺灰色表示 Qt 程式庫中識別字的語法高亮度。

首先,引進必要的標頭檔,然後在 main() 中分別建立 QApplicationEncryptWindow 物件,並以後者呼叫 show() 來顯示視窗,最後回傳前者呼叫 exec() ,告訴作業系統 EncryptWindow 的視窗正在執行,直到使用者結束為止。

main.cpp 在後續都不會進行修改,這是 Qt 程式的基本執行程式,所有的視窗功能都由 EncryptWindow 類別設置,因此往後只需要修改擴充 EncryptWindow 即可。

至於 EncryptWindow 類別的宣告放在 encryptwindow.h ,以下為檔案內容

#ifndef ENCRYPTWINDOW_H
#define ENCRYPTWINDOW_H

#include <QMainWindow>

namespace Ui {
class EncryptWindow;
}

class EncryptWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit EncryptWindow(QWidget *parent = nullptr);
    ~EncryptWindow();

private:
    Ui::EncryptWindow *ui;
};

#endif // ENCRYPTWINDOW_H

第 1 行及第 2 行為前置處理器指令 (preprocessor directive) , #ifndef 用來判斷是否沒有定義 encryptwindow.h ,如果沒有定義則用 #define 定義

#ifndef ENCRYPTWINDOW_H
#define ENCRYPTWINDOW_H

這個前置處理的目的是為了避免重複引入相同的標頭檔,因為重複引入會產生編譯錯誤,簡單講就是編譯器 (compiler) 不知道要用哪一個標頭檔,然後用了 #ifndef 最後一行就要用 #endif 結束

#endif // ENCRYPTWINDOW_H

接下來用 namespace 宣告了命名空間 (name space) Ui

namespace Ui {
class EncryptWindow;
}

Ui 實際上定義在 ui_encryptwindow.h 裡,這是 Qt Creator 在編譯後自動建立的程式檔案, Ui 裡定義的 EncryptWindow 類別就是實際的視窗物件。

現在不需要太擔心 Ui::EncryptWindow 的內容,稍候我們會用 Designer 直接在 Qt Creator 的視窗中拉出 GUI 外觀,這部份 Qt Creator 會自動修改 ui_encryptwindow.h ,所以認識一下 Ui 是代表什麼就好囉!

EncryptWindow 繼承 (inherit)QMainWindow ,至於繼承是寫在類別宣告的第 10 行,在 EncryptWindow 之後用冒號接父類別識別字

class EncryptWindow : public QMainWindow

繼承是物件導向程式設計 (object-oriented programming) 的一個特性,子類別 (subclass) 可從父類別 (superclass) 承接所有 publicprotected 的成員 (member) ,當然也可以再定義專屬於子類別的成員。這是說如果有很多個類別具有共通的特性,就可以把共通的部份抽出來設計父類別,然後用子類別去繼承,這些子類別再各自定義自己需要的成員。

繼承」的英文原文為 inherit ,這個詞泛指從什麼得到什麼,「遺傳」的英文原文也是 inherit ,由於中文的「繼承」與「遺傳」兩者詞義有些不同,「繼承」有隱喻前者已死,後者取代前者的意思,物件導向的機制並無此意,反而比較接近「遺傳」,不過程式界沿襲「繼承」一詞已久,特此說明。

倒是要注意一個地方,現在 encryptwindow.h 中的 EncryptWindowUi::EncryptWindow 是不一樣的類別,前者是 MVC 中的 C ,後者則是 MVC 中的 V ,為了讓 C 能控制 V ,因此 EncryptWindow 需要 Ui::EncryptWindow 型態的資料成員

private:
    Ui::EncryptWindow *ui;
};

是的,像是拉出個按鈕,然後按下按鈕要有什麼反應都透過 ui 來設定就可以了,除此之外, EncryptWindow 的第一行有

Q_OBJECT

Q_OBJECT 為 Qt 預設的巨集 (macro) ,因此只要建立視窗物件都會先執行這個巨集

最後看到有兩個成員函數 (member function)

public:
    explicit EncryptWindow(QWidget *parent = nullptr);
    ~EncryptWindow();

建構函數 (constructor) EncryptWindow()explicit 宣告,這是避免建立 EncryptWindow 物件 (object) 時進行隱性型態轉換,而另一個有 ~ 符號的則是解構函數 (destructor) ,這是物件結束時執行的函數 (function) ,這牽涉到記憶體管理的內容,下面我們先來討論一下記憶體管理囉!

相關教學影片

中英文術語對照
專案 project
類別 class
標頭檔 header file
前置處理器指令 preprocessor directive
編譯器 compiler
命名空間 name space
繼承 inherit
物件導向程式設計 object-oriented programming
子類別 subclass
父類別 superclass
成員 member
巨集 macro
成員函數 member function
建構函數 constructor
物件 object
解構函數 destructor
函數 function
重點整理
1. 專案 encrypt_gui 中, M 是指 Encrypt 類別 (encrypt.cpp) , V 為 Qt Creator 自動產生的 encryptwindow.ui , C 則是 encryptwindow.cpp
2. Qt Creator 建立專案後,所有相關檔案都會放到同一個資料夾(目錄)中。
3. #ifndef#define#endif 等都是前置處理器指令。
4. 關鍵字 namespace 用來宣告命名空間。
5. 繼承是物件導向程式設計的特性之一,子類別可以承接父類別的 publicprotected 成員。
6. Q_OBJECT 為 Qt 預設的巨集。
7. 相對於建構函數,具有 ~ 符號的稱為解構函數。
問題與討論
1. 為什麼 Qt 的基本執行程式 main.cpp 中要建立 QApplication 物件?
2. 巨集是什麼?為什麼 Qt 程式要先執行 Q_OBJECT 巨集?
3. 除了 #ifndef#define#endif 外還有其他的前置處理器指令嗎?
4. 為什麼要宣告命名空間 Ui
5. 繼承的意義為何?除了繼承外,物件導向程式設計還有哪些特性?
練習
1. 承接單元 21 練習發展完成的陣列版 GuessGame 類別,重構成字串版,為此版本先設計標頭檔,將新程式寫在 exercise2501.h 中,記得先引進標準程式庫中的 string ,並將 ab 改成資料成員。
2. 承上題,重新設計 set_game() ,將實作檔案寫在 exercise2501.cpp 中。

上一頁 單元 24 - Qt Creator 使用簡介
回 C++ 入門指南目錄
下一頁 單元 26 - 記憶體管理
回 C++ 教材
回程式語言教材首頁