類別 (class) 用來設計自己需要的物件 (object) ,這是說,類別是物件的藍圖。 C++ 中設計類別使用關鍵字 (keyword) class ,後面接大括弧宣告 (declare) 類別的成員 (member)
成員可以是資料 (data) 、函數 (function) 與建構函數 (constructor) ,資料其實就是專屬於類別的變數 (variable) ,我們在這裡沿用 C++ 的習慣稱之為資料成員 (data member) ,同樣的,函數也是專屬於類別的,稱之為成員函數 (member function) ,至於建構函數屬於特別的成員函數,用來建立該類別物件的專屬函數。
因為建構函數用來建立物件,所以建構函數沒有回傳值 (return value) ,或著可以這麼想像,建構函數預設回傳物件自己本身,因此無須宣告回傳值。
另外,類別定義必須利用存取標籤 (access label) public 或 private 將成員的權限歸類,屬於 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.cpp
功能:示範定義類別
作者:張凱慶 */
此例中的 Demo 類別宣告三個 public 成員, a 、 b 為成員變數, DoSomething() 為成員函數,記得, class 大括弧的最後要加上分號
// 宣告類別
class Demo {
// 宣告 public 成員
public:
int a;
int b;
int DoSomething();
};
底下為實作 Demo 類別中的 DoSomething() 成員函數
// 實作 Demo 的 DoSomething() 成員函數
int Demo::DoSomething() {
return a + b;
}
DoSomething() 的工作很簡單,就是回傳兩個成員變數 a 與 b 的相加值。這裡須注意定義成員函數時,必須在成員函數名稱前加上所屬類別名稱接兩個冒號
int Demo::DoSomething() {
這是標明 DoSomething() 是屬於 Demo 類別的,連續兩個冒號 :: 為作用域運算子 (scope operator) 。沒有這樣寫的話,編譯器 (compiler) 會把 DoSomething() 當成普通的函數處理。
也可以直接把成員函數的實作直接寫在宣告的地方,我們建議分開寫,因為小程式可能看起來沒差,大型程式在習慣上會把宣告放在標頭檔 (header file) 。
下面的 main() 直接用小數點運算子設定 a 與 b ,然後印出 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;
}
編譯執行看看結果吧
這個例子我們只用到 public ,接下來我們要繼續介紹 private ,將資料有效的封裝 (encapsulation) 在物件裡。
相關教學影片
- 第五堂課導覽 ⇨ YouTube 頁面連結
- 類別 ⇨ YouTube 頁面連結
- 封裝 ⇨ YouTube 頁面連結
- static 、 const 與 mutable 成員 ⇨ YouTube 頁面連結
- 巢狀類別 ⇨ YouTube 頁面連結
- Copy 建構函數 ⇨ YouTube 頁面連結
- 多載運算子 ⇨ YouTube 頁面連結
- 繼承 ⇨ YouTube 頁面連結
- 多型 ⇨ YouTube 頁面連結
- 類別樣板 ⇨ YouTube 頁面連結
- 標頭檔與標準程式庫 ⇨ YouTube 頁面連結
中英文術語對照 | |
---|---|
類別 | class |
物件 | object |
關鍵字 | keyword |
宣告 | declare |
成員 | member |
資料 | data |
函數 | function |
建構函數 | constructor |
變數 | variable |
資料成員 | data member |
成員函數 | member function |
回傳值 | return value |
存取標籤 | accsee label |
繼承 | inherit |
作用域運算子 | scope operator |
標頭檔 | header file |
編譯器 | compiler |
封裝 | encapsulation |
重點整理 |
---|
1. 類別是物件的藍圖,每一個類別都可以定義資料成員及成員函數,宣告類別使用關鍵字 class ,每個成員都要用存取標籤分類,大括弧的最後要加上分號。 |
2. 建構函數屬於特別的成員函數,用來建立該類別的物件。 |
3. 成員函數的實作通常會放在類別宣告外,需要標上類別名稱與作用域運算子表示屬於哪個類別。 |
4. 宣告建立類別的物件(變數)後,可用小數點運算子指派數值給 public 的成員變數,也可用小數點運算子呼叫成員函數。 |
問題與討論 |
---|
1. 為什麼類別要有專屬的變數及函數?想一想,這跟物件的意涵有什麼關聯? |
2. 成員函數跟一般的函數有什麼不同?資料成員跟一般的變數又有什麼不同? |
3. 除了建構函數、成員函數及資料成員之外,類別中還有其他種類的成員嗎? |
4. 為什麼要有建構函數?建構函數的用途是什麼? |
5. 為什麼成員函數的實作要放在類別宣告之外? |
練習 |
---|
1. 寫一個程式 exercise1001.cpp ,裡頭設計一個類別 IntegerDemo , IntegerDemo 有一個 int 的成員變數 value ,另有一個沒有回傳值的成員函數 add() , add() 有一個 int 參數,呼叫 add() 時會把參數與 value 相加,結果儲存在 value ,執行部分先將 value 設定為 25 ,再呼叫 add() 以 24 當參數。 |
2. 承上題,另寫一個程式 exercise1002.cpp ,改成由使用者輸入兩個整數。 |
3. 承上題,另寫一個程式 exercise1003.cpp ,加入成員函數 subtract() , subtract() 沒有回傳值另外需要一個 int 參數,同樣呼叫 subtract() 是將 value 減去參數值,最後結果儲存在 value 。 |
4. 承上題,另寫一個程式 exercise1004.cpp ,繼續擴充 IntegerDemo ,加入乘法的成員函數。 |
5. 承上題,另寫一個程式 exercise1005.cpp ,繼續擴充 IntegerDemo ,加入除法的成員函數。 |
6. 寫一個程式 exercise1006.cpp ,仿照 IntegerDemo ,將成員函數改成計算階層值,結果儲存在 value 。 |
7. 寫一個程式 exercise1007.cpp ,仿照 IntegerDemo ,將成員函數改成計算費氏數列,結果儲存在 value 。 |