Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chap 18 類別與物件 夫有土者,有大物也。有大物者,不可以物。 物而不物,故能物物。 明乎物物者之非物也,豈獨治天下百姓而已哉!

Similar presentations


Presentation on theme: "Chap 18 類別與物件 夫有土者,有大物也。有大物者,不可以物。 物而不物,故能物物。 明乎物物者之非物也,豈獨治天下百姓而已哉!"— Presentation transcript:

1 Chap 18 類別與物件 夫有土者,有大物也。有大物者,不可以物。 物而不物,故能物物。 明乎物物者之非物也,豈獨治天下百姓而已哉!
《莊子﹒外篇 在宥第十一》 本章介紹定義類別,以及如何使用類別來定義物件的基本語法。這種使用類別和物件來設計程式的方式稱為「以物件為基礎的程式設計」(object-based programming)。

2 類別與物件 18.1 程式設計方法的演進 18.2 抽象化和資料的隱藏 18.3 物件與類別的關係
18.1 程式設計方法的演進 18.2 抽象化和資料的隱藏 18.3 物件與類別的關係 18.4 以物件為基礎的銀行帳戶操作程式實例 18.5 以物件為基礎的電梯操作模擬範例 18.6 朋友函數

3 程式設計方法的演進 函數 (function,或稱為副程式,subroutine)。
結構式程式設計 (structured programming)。 以程序為基礎的程式設計 (procedural-based programming)。 以物件為基礎的程式設計 (object-based programming)。 物件導向程式設計 (object-oriented programming,簡稱OOP)。

4 物件 (objects) 具有各種特質 (attributes)。 能夠展現各種行為 (behaviors)。

5 物件導向(object-oriented) 的程式設計
不是只重視處理問題的步驟: 在程式中保留各種物件的特性,規劃出使用者與物件,以及物件與物件間的互動關係,以完成程式資料處理的功能。 物件導向程式設計的來源: 電腦模擬 (Computer simulation) 。 Windows作業系統的誕生。

6 抽象化(Abstraction) 在思考問題和規劃程式的時候,先考慮: (1) 在整個系統裏面,有那些參與的物 件。 (2) 這些物件有什麼特質,能夠展現什 麼行為。 (3) 外界與物件,以及物件與物件間如 何互動。

7 封裝(Encapsulation) -- 資料的隱藏
物件與外界的內外區隔。 物件的特質、行為等實作的細節則被封裝在物件的內側。 通常我們可以用一個蛋的三重構造來比擬一個物件: 圖18.1.2 物件的三重構造

8 物件的三重構造 1. 特徵值 (attributes): 代表物件的狀態。 2. 介面 (interface): 可以和外界直接接觸。
3. 行為 (behaviors): 經由介面與外界互動而改變內部的特徵值,並把反應經由介面表現出來。

9 物件導向程式設計的好處 1. 提高程式的再利用率 2. 問題和程式間更直接的對應關係 區隔清楚,功能內涵,能夠發揮提綱挈領的特性。
1. 提高程式的再利用率 區隔清楚,功能內涵,能夠發揮提綱挈領的特性。 嚴謹的介面限制,避免資料和函數間不受控制的互動。 2. 問題和程式間更直接的對應關係 問題領域 (problem domain) 的每個物件,都可在程式領域 (program domain)找到相對應的物件; 可以比較直觀的進行程式規劃。 變得更有組織,更容易理解,也更易設計和除錯。

10 物件的特性 1. 狀態 (state)。 以一部電梯為例,它的狀態包括目前所在的樓層位置,目前的速度,要前往的目標樓層,內部乘客人數,總重,等與運作有關的細節。 2. 行為 (behavior) 。 以一部電梯為例,它的行為則有:接受按鈕呼叫,接受目的樓層選擇,以及驅動升降等功能,可以與外界互動或改變狀態。

11 問題領域物件與程式物件間的對應關係 成員函數又稱為方法 (methods);它能夠改變資料成員,具體的呈現物件的行為。
問題領域的物件 (Problem space objects) 軟體物件 (Software objects) 狀態(states) 行為(behaviors) 資料成員(data members) 成員函數(member functions)

12 訊息 (messages) 的三個要素 1.接受此訊息的物件名稱。 2.所要觸動的方法。 3.執行此方法所需要的參數。 傳送訊息相當於呼叫成員函數。

13 類別(class) 類別是廣義的資料型態, 是某類物件的藍圖,定義了所有這類物件擁有的資料成員和成員函數。 struct可以包括不同種類的基本資料型態,而類別 (class) 更進一步把成員函數都包裝在裏面。

14 int、struct和class資料型態定義的比較

15 public和private成員 「private:」之後的成員 (包括資料成員和成員函數) 只有同一個class內的成員函數才可以取用和呼叫。 在「public:」之後的成員開放給程式內的所有敘述。 struct除了內部成員的預設開放程度都是public以外,它和class沒有任何差異。

16 介面(Interface) 被設定為private的資料成員和成員函數必需透過被設定為public的函數成員才能存取。 public函數成員稱為這個class的介面。

17 成員函數的實作 (Implementation of member functions)
在class的本體之內實作inline成員函數 在class的本體之外實作inline成員函數 在class的本體之外實作一般的成員函數

18 在class的本體 (body) 之內實作inline成員函數
void CheckRate() {cout << "目前存款利率是: " << Rate << '%' << endl;}

19 在class的本體之外實作inline成員函數
必需在傳回資料型態之前加上關鍵字「inline」,然後在成員函數的名稱之前加上範圍確認運算子 (scope resolution operator) 「::」。例如: inline void Account::CheckBalance() { cout << "目前 " << Id << " 的帳戶餘額是 " << Balance << " 元\n"; return; }

20 在class的本體之外實作一般的成員函數
這個語法和inline成員函數的定義是完全一樣的,只是少了關鍵字「inline」而已。例如: void Account::WithDraw(int Cash) { Balance -= Cash; cout << Id << " 提款 " << Cash << " 元後," << "目前帳戶餘額是 " << Balance << " 元\n"; return; }

21 成員函數的呼叫 呼叫public成員函數是外界與物件互動的唯一方式,也是傳送訊息 (message) 給物件的方式。如圖18.3.1所示:

22 const成員函數 在執行時不應更動資料成員。 其語法是將關鍵字const放在參數列的括弧後面。例如:
void CheckBalance() const; 它的實作部份也要改成: void Account::CheckBalance() const { cout << "目前 " << Id << " 的帳戶餘額是 " << Balance << " 元\n"; return; }

23 const inline成員函數 inline void Account::CheckBalance() const {
cout << "目前 " << Id << " 的帳戶餘額是 " << Balance << " 元\n"; return; }

24 建構函數(constructor)與解構函數(destructor)
在Account類別的宣告中,有兩個成員函數非常特別,分別是: Account(); ~Account(); 它們有兩個特徵是其它成員函數所沒有的: 1. 成員函數的名稱與類別名稱相同。 2. 沒有傳回資料型態 (return data type),連void也沒有。

25 建構函數與解構函數 當我們進行物件的定義時,建構函數就會被呼叫。 解構函數會在物件離開它的作用範圍 (scope) 時自動被呼叫。

26 預設建構函數(default constructor)
由編譯器提供的預設建構函數沒有實值內容,因此沒有產生任何影響。 自己建立沒有參數的建構函數來對物件進行初始化的動作。例如: Account::Account() {Balance = 0;} 這時候,編譯器將不會再製造一個空的建構函數,由於沒有引數,它仍然稱為「預設的建構函數」。

27 可以接受參數的建構函數 應用C++ 允許函數重載 (overload) 的特性,可以同時建立一個可以接受參數的建構函數。例如:
Account::Account(int N) {Balance = N;}

28 具有初始化功能的預設建構函數 (default constructor)
有兩種寫法: (1)標準成員函數的語法。例如: Account::Account() {Balance = 0;} (2)具有初始功能的縮寫語法。  建構函數名稱():資料成員名稱 (初始值) { } 例如:   Account::Account(): Balance(0) {} 如果有兩個以上的資料成員需要初始化,則可以一併完成:   Account::Account(): A1(5), A2(1){} 這兩種語法也可以在類別本體內定義。

29 解構函數 (destructor) 解構函數的名稱是由一個波浪符號「~」加在類別名稱之前所構成,不接受任何參數。
只有由編譯器所自動建立的解構函數才稱為「預設的解構函數」(default constructor)。 解構函數會在物件離開它的作用範圍 (scope) 時自動被呼叫。 擔任回收記憶資源的工作。 內建資料型態所定義的區域變數不需要借助解構函數,即可自動從堆疊 (stacks) 回收記憶資源。 對於陣列而言,程式設計者必需在解構函數內使用關鍵字 delete來達到這個目的。

30 建構函數與解構函數的自動呼叫 例如: // ... 其他敘述 { Account John; // 在區塊內定義名叫John的物件
// John.Account()在此處自動被呼叫 } // John.~Account()在此處自動 // 被呼叫

31 static成員 修飾詞static表示所有由這個類別所定義的物件,都共用此資料成員。 如果static資料成員遭到修改,所有的物件都會因而受到影響。 static資料成員也常被拿來累計由類別所定義的物件數目。

32 物件佔有的記憶體大小 由public和private資料成員的大小總和來決定。 不包括成員函數和static資料成員。

33 以物件為基礎的銀行帳戶操作程式範例 這個程式的功能是用來建立銀行帳戶 (account),並經由存款(deposit) 或提款 (withdraw) 來更動存款餘額 (balance)。 類別 Account與外界的互動必須透過介面Deposit()、WithDraw()、CheckBalance()、CheckRate() 和CheckCount() 來進行。 每一個實例 (instances) 的內部都有Balance,Id,Rate和Count四個特徵值,其中Rate和Count被所有實例共用,因此宣告為static變數。

34 以物件的觀點描述類別Account的組成和功能

35 標頭檔AccountClass.h 宣告類別Account,以及定義Deposit(),CheckBalance()、CheckCount() 和CheckRate() 四個inline成員函數。 此外,在這個標頭檔內設定static變數Rate和Count的初始值。 變數Rate和Count是private,因此必需透過成員函數CheckRate() 和CheckCount() 才能取用它。

36 範例程式 檔案 AccountClass.h // AccountClass.h #ifndef ACCOUNTCLASS_H
#define ACCOUNTCLASS_H #include <iostream> #include <iomanip> using namespace::std; //---- 宣告類別 Account class Account { private: static float Rate; // static 變數 static int Count; // static 變數 int Balance; char Id[20];

37 public: Account(); // 預設建構函數 Account(char[]); // 建構函數-1 Account(char[], int); // 建構函數-2 ~Account(); // 解構函數 void Deposit (int); void WithDraw(int); void CheckBalance() const; void CheckRate () const {cout << "目前存款利率是: " << Rate << '%' << endl;} void CheckCount() const; };

38 } // -- 設定 static 變數初始值 ---------------------
float Account::Rate = 5.8; int Account::Count = 0; // -- 定義 inline 成員函數 Deposit() inline void Account::Deposit(int CashInput) { Balance += CashInput; cout << setw(8) << Id << " 存款 " << CashInput << " 元後 " << "目前帳戶餘額是 " << Balance << " 元\n"; return; }

39 // -- 定義 inline 成員函數 CheckBalance()-------------
inline void Account::CheckBalance() const { cout << "目前 " << setw(8) << Id << " 的帳戶餘額是 " << Balance << " 元\n"; return; } // -- 定義 inline 成員函數 CheckCount() inline void Account::CheckCount() const cout << "目前銀行共有 " << Count << " 個帳戶.\n"; #endif

40 檔案AccountDef.cpp 定義成員函數WithDraw(),建構函數Account(),Account(char[]),Account(char [], int),以及解構函數 ~Account()。 在建構函數和解構函數的實作內容加上了簡短的輸出訊息。 建構函數和解構函數內分別對static變數Count做遞增和遞減運算。

41 範例程式 檔案 AccountDef.cppp
#include "AccountClass.h" #include <cstring> //-- 定義預設建構函數 Account() Account::Account() { cout << "設定銀行帳戶" << endl; Balance = 0; Account::Count++; cout << "目前尚未輸入帳戶名稱.\n"; return; }

42 //-- 定義建構函數 Account() ----------------------
Account::Account(char Name[]) { strcpy(Id, Name); cout << "設定 " << left << setw(8) << Id << " 的銀行帳戶" << endl; Balance = 0; Account::Count++; cout << “目前 ” << setw(8) << Id << “ 帳戶餘額是 “ << Balance << " 元\n"; return; }

43 // -- 定義建構函數 Account() ---------------------
Account::Account(char Name[], int N) { strcpy(Id, Name); cout << "設定 " << setw(8) << Id << " 的銀行帳戶" << endl; Balance = N; Account::Count++; cout << "目前 " << setw(8) << Id << " 帳戶餘額是 " << Balance << " 元\n"; return; } //-- 定義解構函數 ~Account() Account::~Account() cout << "徹消 " << setw(8) << Id << " 的銀行帳戶" << endl; Account::Count--; return;

44 // -- 定義成員函數 WithDraw() ------------------------
void Account::WithDraw(int Cash) { if (Cash > Balance) cerr << "存款不足! " << setw(8) << Id << " 這次提款不成." << endl; return; } Balance -= Cash; cout << setw(8) << Id << " 提款 " << Cash << " 元後," << "目前帳戶餘額是 " << Balance << " 元\n";

45 檔案AccountMain.cpp 主程式。 在不同的階段定義John、William、Cathy和Albert四個物件。
呼叫WithDraw(),CheckBalance() 和Deposit() 等成員函數以更動或顯示這些物件的存款餘額。 藉由函數sizeof() 檢查物件John的大小。 檢查static變數Count可以知道目前實例 (instances) 的存在數量。 Albert被定義在區塊內,因此它是個區域物件。

46 範例程式 檔案 AccountMain.cpp
#include "AccountClass.h" // 主程式 int main() { cout << "\n(1)" << endl; // (1) Account John("John"), William("William"); // 定義兩個帳戶 Account Cathy ("Cathy", 12456); // 定義帳戶 Cathy Cathy.CheckCount(); Cathy.WithDraw(450); // 帳戶 Cathy 提款 William.Deposit(5000); // 帳戶 Cathy 存款 cout << "\n(2)" << endl; // (2) cout << "Size of John is: " << sizeof(John) << endl;

47 John.CheckBalance(); Cathy.CheckBalance(); William.CheckBalance(); John.WithDraw(450); cout << "\n(3)" << endl; { // (3) 區塊開始 Account Albert("Albert", 1200); // 定義帳戶 Albert Albert.CheckCount(); Albert.WithDraw(258); // 帳戶 Albert 提款 Albert.CheckBalance(); } // (3) 區塊結束 Cathy.CheckCount(); cout << "\n(4)" << endl; John.CheckRate(); return 0; }

48 執行結果 (1) 設定 John 的銀行帳戶 目前 John 帳戶餘額是 0 元 設定 William 的銀行帳戶
設定 Cathy 的銀行帳戶 目前 Cathy 帳戶餘額是 元 目前銀行共有 3 個帳戶. Cathy 提款 450 元後,目前帳戶餘額是 元 William 存款 5000 元後 目前帳戶餘額是 5000 元 (2) Size of John is: 24 目前 John 的帳戶餘額是 0 元 目前 Cathy 的帳戶餘額是 元 目前 William 的帳戶餘額是 5000 元 存款不足! John 這次提款不成.

49 (3) 設定 Albert 的銀行帳戶 目前 Albert 帳戶餘額是 1200 元 目前銀行共有 4 個帳戶. Albert 提款 258 元後,目前帳戶餘額是 942 元 目前 Albert 的帳戶餘額是 942 元 徹消 Albert 的銀行帳戶 目前銀行共有 3 個帳戶. (4) 目前存款利率是: 5.8% 徹消 Cathy 的銀行帳戶 徹消 William 的銀行帳戶 徹消 John 的銀行帳戶

50 以物件為基礎的電梯操作模擬範例 電梯 (elevator) 的操作方式不外下列數種: 1. 從使用者所在的樓層呼叫電梯。
1. 從使用者所在的樓層呼叫電梯。 2. 使用者設定要前往的目標樓層。 3. 將使用者載至目標樓層。 為了簡化模擬,我們暫時忽略諸如: 1. 呼叫電梯時,有向上和向下兩種選擇。 2. 使用者可以要求電梯把門即時關上,或繼續保持開啟狀態。 3. 超重時會以聲音示警。 等細節,並且以顯示電梯目前所在位置的方式模擬電梯的運動。

51 以物件的觀點描述使用者和電梯間的互動

52 宣告類別ElevatorClass,包括:
標頭檔ElevatorClass.h 宣告類別ElevatorClass,包括:  Call(),Select() 和Move() 三個成員函數。其中Move() 是private成員函數。  建構函數Elevator() 以及解構函數 ~Elevator()。  CurrentFloor和Count兩個資料成員。其中Count是static變數

53 範例程式 檔案 ElevatorClass.h
#ifndef ELEVATORCLASS_H #define ELEVATORCLASS_H #include <iostream> using namespace::std; //---- 宣告類別 Elevator class Elevator { private: int CurrentFloor; void Move(int);

54 public: Elevator(); // 預設建構函數 Elevator(int); // 建構函數(可設定初值) ~Elevator(); // 解構函數 void Call(int); void Select(int); static int Count; // static 變數 }; // -- 設定 static 變數初始值 int Elevator::Count = 0; #endif

55 檔案ElevatorDef.cpp 定義了建構函數Elevator(),解構函數~Elevator()以及Call(),Select() 和Move() 三個成員函數。 在private成員函數Move()的實作內容加上了簡短的輸出訊息 (例如:“燈號: 6樓”),以便模擬電梯移動時的燈號顯示。 重載的建構函數Elevator() 可以接受參數,以便設定電梯的起始位置。 建構函數和解構函數內分別對static變數Count做遞增和遞減運算,以確實掌握程式執行中物件的數量。

56 範例程式 檔案 ElevatorDef.cpp
#include "ElevatorClass.h" Elevator::Elevator() // 定義預設建構函數 { cout << "建構函數被呼叫" << endl; CurrentFloor = 1; Count++; return; } Elevator::Elevator(int N) // 定義建構函數 (可設定初值) CurrentFloor = N; Count++; return; Elevator::~Elevator() // 定義解構函數 cout << "解構函數被呼叫" << endl; Count--; return;

57 void Elevator::Call(int N) // 定義成員函數 Call()
{ Move (N); cout << "電梯到了, 請進.\n"; return; } // ---- 定義成員函數 Select() void Elevator::Select(int N) cout << "載您到 " << N << " 樓.\n"; if (N > CurrentFloor) cout << "電梯向上.\n"; else cout << "電梯向下.\n"; cout << "電梯已到 " << CurrentFloor << " 樓, 謝謝光臨.\n"; return;

58 // ---- 定義 private成員函數 Move() -----------------
void Elevator::Move(int Target) { cout << "電梯門要關了, 請小心." << endl; int Start = CurrentFloor; cout << "電梯目前在 " << CurrentFloor << " 樓\n"; if (Target >= CurrentFloor) for (CurrentFloor = Start; CurrentFloor <= Target; CurrentFloor++) cout << " 燈號: " << CurrentFloor << " 樓\n"; CurrentFloor--; }

59 else { for (CurrentFloor = Start; CurrentFloor >= Target; CurrentFloor--) cout << “ 燈號: ” << CurrentFloor << “ 樓”  << endl; CurrentFloor++; } cout << "電梯門要開了, 請小心." << endl; return;

60 檔案ElevatorMain.cpp 主程式。 分別在兩個地方定義A和B兩部電梯,並藉由成員函數Call() 和Select() 叫用。 在程式執行當中檢查static變數Count的值,以了解目前程式內的電梯數量。

61 範例程式 檔案 ElevatorMain.cpp
#include "ElevatorClass.h" // 主程式 int main() { // (1) cout << "(1)" << endl; Elevator A; // 定義電梯 A cout << "從 5 樓呼叫:" << endl; A.Call(5); // 呼叫電梯 A A.Select(2); // 設定電梯 A 到 2 樓 cout << "目前 Count的值是: " << A.Count << endl;

62 // (2) cout << "(2)" << endl; Elevator B(3); // 定義電梯 B cout << "從 4 樓呼叫:" << endl; B.Call(4); // 呼叫電梯 B B.Select(8); // 設定電梯 B 到 8 樓 cout << "目前 Count 的值是: " << B.Count << endl; return 0; }

63 執行結果 (1) 建構函數被呼叫 從 5 樓呼叫: 電梯門要關了, 請小心. 電梯目前在 1 樓 燈號: 1 樓 燈號: 2 樓
燈號: 3 樓 燈號: 4 樓 燈號: 5 樓 電梯門要開了, 請小心. 電梯到了, 請進.

64 載您到 2 樓. 電梯向下. 電梯門要關了, 請小心. 電梯目前在 5 樓 燈號: 5 樓 燈號: 4 樓 燈號: 3 樓 燈號: 2 樓 電梯門要開了, 請小心. 電梯已到 2 樓, 謝謝光臨. 目前 Count 的值是: 1

65 (2) 建構函數被呼叫 從 4 樓呼叫: 電梯門要關了, 請小心. 電梯目前在 3 樓 燈號: 3 樓 燈號: 4 樓 電梯門要開了, 請小心. 電梯到了, 請進. 載您到 8 樓. 電梯向上.

66 電梯目前在 4 樓 燈號: 4 樓 燈號: 5 樓 燈號: 6 樓 燈號: 7 樓 燈號: 8 樓 電梯門要開了, 請小心. 電梯已到 8 樓, 謝謝光臨. 目前 Count 的值是: 2 解構函數被呼叫

67 朋友函數 friend函數本身並非類別內的成員函數,卻被允許直接取用private成員。 函數無法自行宣告自己是某類別的friend函數,必需由類別宣告才可以。

68 在類別內宣告friend函數 只要在函數的宣告之前加上關鍵字friend即可。 關鍵字friend的後面沒有冒號「:」。
以模擬電梯操作的程式為例,我們可以將類別Elevator的成員函數Call() 和Select() 宣告成friend函數: friend void Call(Elevator &, int); friend void Select(Elevator &, int); private成員函數、建構函數及解構函數都不能宣告為friend函數。 在friend函數的參數列中必需要有這個物件的參照,或是物件的指標。

69 範例程式FEClass.h 包括friend函數宣告的完整標頭檔FEClass.h,可以拿來和ElevatorClass.h仔細比較。

70 範例程式 檔案 FEClass.h // FEClass.h #ifndef FECLASS_H #define FECLASS_H
#include <iostream> using namespace::std; //---- 宣告類別 Elevator class Elevator { friend void Call(Elevator&, int); friend void Select(Elevator&, int); public: Elevator(); // 預設建構函數 Elevator(int); // 建構函數(可設定初值) ~Elevator(); // 解構函數 static int Count; // static 變數

71 private: int CurrentFloor; void Move(int); }; // -- 設定 static 變數初始值 int Elevator::Count = 0; #endif

72 friend函數的定義 和一般函數的定義一樣,不需要外加類別名稱,連關鍵字「friend」也不用加。
例如friend函數Call() 的定義: void Call(Elevator& E, int N) { E.Move (N); cout << "電梯到了, 請進." << endl; return; }

73 範例程式FEDef.cpp 列出包括兩個friend函數Call() 和Select() 定義之完整檔案FEDef.cpp,可以拿來和ElevatorDef.cpp仔細比較。

74 範例程式 檔案 FEDef.cpp // FEDef.cpp #include "FEClass.h"
// -- 定義 friend 函數 Call() void Call(Elevator& E, int N) { E.Move (N); cout << "電梯到了, 請進." << endl; return; }

75 // -- 定義 friend 函數 Select() ----------------------
void Select(Elevator& E, int N) { cout << "載您到 " << N << " 樓." << endl; if (N > E.CurrentFloor) cout << "電梯向上." << endl; else cout << "電梯向下." << endl; E.Move (N); cout << "電梯已到 " << E.CurrentFloor << " 樓, 謝謝光臨.\n"; return; }

76 // --- 定義預設建構函數 Account() --------------------
Elevator::Elevator() { cout << "建構函數被呼叫" << endl; CurrentFloor = 1; Count++; return; } // --- 定義建構函數 Account() (可設定初值) Elevator::Elevator(int N) CurrentFloor = N;

77 // -- 定義解構函數 ~Elevator() -----------------------
Elevator::~Elevator() { cout << "解構函數被呼叫" << endl; Count--; return; } // -- 定義 private函數 Move() void Elevator::Move(int Target) cout << "電梯門要關了, 請小心." << endl; int Start = CurrentFloor; cout << "電梯目前在 " << CurrentFloor << " 樓" << endl;

78 if (Target >= CurrentFloor)
{ for (CurrentFloor = Start; CurrentFloor <= Target; CurrentFloor++) cout << " 燈號: " << CurrentFloor << " 樓" << endl; CurrentFloor--; }

79 else { for (CurrentFloor = Start; CurrentFloor >= Target; CurrentFloor--) cout << " 燈號: " << CurrentFloor << " 樓" << endl; CurrentFloor++; } cout << "電梯門要開了, 請小心." << endl; return;

80 在主程式內使用friend函數 可以寫成 語法接近傳統的程序式 (procedural) 語言,卻保有「以物件為基礎的程式設計」的所有功能。
Call(A, 5); // 呼叫電梯 A Select(B, 2); // 設定電梯 A 到 2 樓 語法接近傳統的程序式 (procedural) 語言,卻保有「以物件為基礎的程式設計」的所有功能。 代價是在friend函數的定義內,每個成員都必需加上物件的名稱。

81 範例程式 檔案 FEMain.cpp // FEMain.cpp #include "FEClass.h"
// 主程式 int main() { // (1) cout << "(1)" << endl; Elevator A; // 定義電梯 A cout << "從 5 樓呼叫:" << endl; Call(A, 5); // 呼叫電梯 A Select(A, 2); // 設定電梯 A到 2 樓 cout << "目前 Count的值是: " << A.Count << endl;

82 // (2) cout << "(2)" << endl; Elevator B(3); // 定義電梯 B cout << "從 4 樓呼叫:" << endl; Call(B, 4); // 呼叫電梯 B Select(B, 8); // 設定電梯 B 到 8 樓 cout << "目前 Count 的值是: " << B.Count << endl; return 0; }


Download ppt "Chap 18 類別與物件 夫有土者,有大物也。有大物者,不可以物。 物而不物,故能物物。 明乎物物者之非物也,豈獨治天下百姓而已哉!"

Similar presentations


Ads by Google