C++ 入門指南 4.01

單元 10 - 類別

-unit10-

類別 (class) 用來設計自己需要的物件 (object) ,這是說,類別是物件的藍圖。 C++ 中設計類別使用關鍵字 (keyword) class ,後面接大括弧宣告 (declare) 類別的成員 (member)

類別 → 成員

成員可以是資料 (data) 函數 (function) 建構函數 (constructor) ,資料其實就是專屬於類別的變數 (variable) ,我們在這裡沿用 C++ 的習慣稱之為資料成員 (data member) ,同樣的,函數也是專屬於類別的,稱之為成員函數 (member function) ,至於建構函數屬於特別的成員函數,用來建立該類別物件的專屬函數。

因為建構函數用來建立物件,所以建構函數沒有回傳值 (return value) ,或著可以這麼想像,建構函數預設回傳物件自己本身,因此無須宣告回傳值。

另外,類別定義必須利用存取標籤 (access label) publicprivate 將成員的權限歸類,屬於 public 的成員可以在程式中的任何地方存取, private 則只能在同個類別裡。

為什麼要對存取權限歸類呢?這是因為物件導向程式設計允許後續定義的類別繼承 (inherit) 之前定義類別的特性,這樣的機制使 public 成員會被繼承,而 private 不能被繼承。還有另一個存取標籤 protected ,不過這不在我們目前的討論範圍。

我們舉一例如下

#include <iostream>

using namespace std;

// 宣告類別
class Demo {
// 宣告 public 成員
public:
    int a;
    int b;
    int DoSomething();
};

// 實作 Demo 的 DoSomething() 成員函數
int Demo::DoSomething() {
    return a + b;
}

// 程式執行的 main()
int main(void) {
    // 宣告並建立 Demo 型態的物件 t
    Demo t;
    t.a = 11; // 直接設定成員變數值
    t.b = 22;
    cout << endl;
    // 呼叫並印出 DoSomething() 的回傳值
    cout << t.DoSomething() << endl;
    cout << endl;

    return 0;
}

/* 《程式語言教學誌》的範例程式
   http://kaiching.org/
   檔名:class_demo.cxx
   功能:示範定義類別
   作者:張凱慶 */

此例中的 Demo 類別宣告三個 public 成員, ab 為成員變數, DoSomething() 為成員函數,記得, class 大括弧的最後要加上分號

// 宣告類別
class Demo {
// 宣告 public 成員
public:
    int a;
    int b;
    int DoSomething();
};

底下為實作 Demo 類別中的 DoSomething() 成員函數

// 實作 Demo 的 DoSomething() 成員函數
int Demo::DoSomething() {
    return a + b;
}

DoSomething() 的工作很簡單,就是回傳兩個成員變數 ab 的相加值。這裡須注意定義成員函數時,必須在成員函數名稱前加上所屬類別名稱接兩個冒號

int Demo::DoSomething() {

這是標明 DoSomething() 是屬於 Demo 類別的,連續兩個冒號 ::作用域運算子 (scope operator) 。沒有這樣寫的話,編譯器 (compiler) 會把 DoSomething() 當成普通的函數處理。

也可以直接把成員函數的實作直接寫在宣告的地方,我們建議分開寫,因為小程式可能看起來沒差,大型程式在習慣上會把宣告放在標頭檔 (header file)

下面的 main() 直接用小數點運算子設定 ab ,然後印出 DoSomething() 的回傳值

// 程式執行的 main()
int main(void) {
    // 宣告並建立 Demo 型態的物件 t
    Demo t;
    t.a = 11; // 直接設定成員變數值
    t.b = 22;
    cout << endl;
    // 呼叫並印出 DoSomething() 的回傳值
    cout << t.DoSomething() << endl;
    cout << endl;

    return 0;
}

編譯執行看看結果吧

-classdemo-

這個例子我們只用到 public ,接下來我們要繼續介紹 private ,將資料有效的封裝 (encapsulation) 在物件裡。

中英文術語對照
存取標籤access label
類別class
編譯器compiler
建構函數constructor
資料data
資料成員data member
宣告declare
封裝encapsulation
函數function
標頭檔header file
繼承inherit
關鍵字keyword
成員member
成員函數member function
物件object
回傳值return value
作用域運算子scope operator
變數variable
重點整理
1. 類別是物件的藍圖,每一個類別都可以定義資料成員及成員函數,宣告類別使用關鍵字 class ,每個成員都要用存取標籤分類,大括弧的最後要加上分號。
2. 建構函數屬於特別的成員函數,用來建立該類別的物件。
3. 成員函數的實作通常會放在類別宣告外,需要標上類別名稱與作用域運算子表示屬於哪個類別。
4. 宣告建立類別的物件(變數)後,可用小數點運算子指派數值給 public 的成員變數,也可用小數點運算子呼叫成員函數。
問題與討論
1. 為什麼類別要有專屬的變數及函數?想一想,這跟物件的意涵有什麼關聯?
2. 成員函數跟一般的函數有什麼不同?資料成員跟一般的變數又有什麼不同?
3. 除了建構函數、成員函數及資料成員之外,類別中還有其他種類的成員嗎?
4. 為什麼要有建構函數?建構函數的用途是什麼?
5. 為什麼成員函數的實作要放在類別宣告之外?
練習
1. 寫一個程式 exercise1001.cxx ,裡頭設計一個類別 IntegerDemoIntegerDemo 有一個 int 的成員變數 value ,另有一個沒有回傳值的成員函數 Add()Add() 有一個 int 參數,呼叫 Add() 時會把參數與 value 相加,結果儲存在 value ,執行部分先將 value 設定為 25 ,再呼叫 Add()24 當參數。 參考程式碼
2. 承上題,另寫一個程式 exercise1002.cxx ,改成由使用者輸入兩個整數。 參考程式碼
3. 承上題,另寫一個程式 exercise1003.cxx ,加入成員函數 Subtract()Subtract() 沒有回傳值,另外需要一個 int 參數,同樣呼叫 Subtract() 是將 value 減去參數值,最後結果儲存在 value參考程式碼
4. 承上題,另寫一個程式 exercise1004.cxx ,繼續擴充 IntegerDemo ,加入乘法的成員函數 Multiply()參考程式碼
5. 承上題,另寫一個程式 exercise1005.cxx ,繼續擴充 IntegerDemo ,加入除法的成員函數 Divide()參考程式碼
6. 承上題,另寫一個程式 exercise1006.cxx ,繼續擴充 IntegerDemo ,加入取餘數的成員函數 Modulo()參考程式碼
7. 寫一個程式 exercise1007.cxx ,仿照 IntegerDemo 設計 FactorialDemo ,利用成員函數 Compute() 計算階層值,參數 n 為第幾個階層數,印出使用者,結果儲存在成員變數 value參考程式碼
8. 寫一個程式 exercise1008.cxx ,仿照 IntegerDemo 設計 FibonacciDemo ,利用成員函數 Compute() 計算費氏數列,參數 n 為第幾個階層數,印出使用者,結果儲存在成員變數 value參考程式碼
9. 寫一個程式 exercise1009.cxx ,設計一個平面座標類別 Point ,至少要有兩個成員變數儲存平面座標 xy ,以及計算距離的成員函數 Distance() ,兩點距離為 xy 座標的差值相加。 參考程式碼
10. 寫一個程式 exercise1010.cxx ,設計一個猜數字遊戲類別 Guess ,至少要有ㄧ個字串型態的成員變數 answer 儲存答案,先設定 answer 後,再印出 answer 值。 參考程式碼
11. 寫一個程式 exercise1011.cxx ,設計一個記錄成員的類別 Member ,至少要有兩個成員變數,一個整數型態 id 儲存成員的編號,另一個字串型態 name 儲存成員的暱稱,設定 id0 以及 name"Alice" ,然後印出兩個成員變數。 參考程式碼
12. 寫一個程式 exercise1012.cxx ,設計一個載入文字的類別 Text ,至少要有ㄧ個字串型態的成員變數 content 儲存載入的文字,設定 content"demo" 然後印出來。 參考程式碼
13. 寫一個程式 exercise1013.cxx ,設計一個乒乓球的類別 Ball ,至少要有ㄧ個 Point 型態成員變數 p 儲存球的座標,把 p 設定為原點然後印出來。 參考程式碼
14. 寫一個程式 exercise1014.cxx ,設計一個控制場景的類別 Scene ,至少要有兩個成員變數,一個整數型態 id 儲存場景的編號,另一個字串型態 text 儲存場景的描述文字,將 id 設定為 0text 設定為 "demo" ,然後印出來。 參考程式碼
15. 寫一個程式 exercise1015.cxx ,設計一個遊戲的類別 Game ,至少要用 BallGuess 型態的成員變數,以及成員函數 Run() ,執行部分放在 Run() ,使遊戲在 Run() 中運作。 參考程式碼

相關教學影片

上一頁 單元 9 - 函數
回 C++ 入門指南 4.01 目錄
下一頁 單元 11 - 物件導向與封裝
回 C++ 教材
回程式語言教材首頁