Microsoft Word - 970617cppFinalSolution.doc



Similar documents
Microsoft Word - 中三選科指南 2014 subject

FY.DOC

天主教永年高級中學綜合高中課程手冊目錄

声 明 本 公 司 全 体 董 事 监 事 高 级 管 理 人 员 承 诺 股 票 发 行 方 案 不 存 在 虚 假 记 载 误 导 性 陈 述 或 重 大 遗 漏, 并 对 其 真 实 性 准 确 性 和 完 整 性 承 担 个 别 和 连 带 的 法 律 责 任 根 据 证 券 法 的 规 定

Strings

婴幼儿护理(四).doc


最新监狱管理执法全书(二百零五)

怎样使孩子更加聪明健康(五).doc

(i) (ii) 97/99/M

二零零六年一月二十三日會議

厨房小知识(四)

妇女更年期保健.doc

小儿传染病防治(上)

<4D F736F F D B875B9B5A448ADFBBADEB27AA740B77EA4E2A5555FA95EAED6A641ADD75F2E646F63>

女性青春期保健(下).doc

避孕知识(下).doc

孕妇饮食调养(下).doc

禽畜饲料配制技术(一).doc

中老年保健必读(十一).doc

i

怎样使孩子更加聪明健康(七).doc

i

马太亨利完整圣经注释—雅歌

Strings

新版 明解C++入門編

02

提问袁小兵:

Microsoft Word - 00教学管理手册 mo.doc

extend

新・解きながら学ぶJava

c_cpp

untitled

2013 C 1 # include <stdio.h> 2 int main ( void ) 3 { 4 int cases, a, b, i; 5 scanf ("%d", & cases ); 6 for (i = 0;i < cases ;i ++) 7 { 8 scanf ("%d %d

第3章.doc

C 1 # include <stdio.h> 2 int main ( void ) { 4 int cases, i; 5 long long a, b; 6 scanf ("%d", & cases ); 7 for (i = 0;i < cases ;i ++) 8 { 9

新婚夫妇必读(二十二).doc

第七讲 继承与多态

Chapter12 Derived Classes

幻灯片 1

学 校 概 况 南 方 医 科 大 学 前 身 为 中 国 人 民 解 放 军 第 一 军 医 大 学, 创 建 于 1951 年,1979 年 被 确 定 为 全 国 重 点 大 学,2004 年 8 月 整 体 移 交 广 东 省, 更 名 为 南 方 医 科 大 学 学 校 是 全 国 首 批

I

<4D F736F F F696E74202D E30382E B3CCA6B3A751BCD0A4CEB5FBBFEFC075B3D3BC74B0D328A643A64C292E BACDBAE65BCD2A6A15D>

(Chi)_.indb

14A 0.1%5% 14A 14A

目 錄 壹 緒 論... 2 貳 明 時 代 背 景 一 明 代 禮 教 之 於 女 性? 母 德 婦 德... 2 二 明 代 婦 女 之 於 士 人? 經 濟 支 柱... 4 參 歸 有 光 一 仕 途... 7 二 家 庭... 7 肆 歸 有 光 文 學 裡 的 女 性 比 較 一 < 項

穨_2_.PDF

女性减肥健身(四).doc

<4D F736F F D20312EA1B6BDCCCAA6D7CAB8F1CCF5C0FDA1B72E646F63>

Microsoft Word - 长安大学.doc

附件

Microsoft Word pdf.doc

中医疗法(下).doc

Labour Department Annual Report

項 訴 求 在 考 慮 到 整 體 的 財 政 承 擔 以 及 資 源 分 配 的 公 平 性 下, 政 府 採 取 了 較 簡 單 直 接 的 一 次 性 減 稅 和 增 加 免 稅 額 方 式, 以 回 應 中 產 家 庭 的 不 同 訴 求 ( 三 ) 取 消 外 傭 徵 費 6. 行 政 長

(f) (g) (h) (ii) (iii) (a) (b) (c) (d) 208

Microsoft Word - 08 单元一儿童文学理论

untitled

第三章

nb.PDF

bnbqw.PDF

南華大學數位論文

Microsoft Word 一年級散文教案.doc

米食天地教案

第32回独立行政法人評価委員会日本貿易保険部会 資料1-1 平成22年度財務諸表等

1. 本文首段的主要作用是 A. 指出 異蛇 的藥用功效 說明 永之人爭奔走焉 的原因 B. 突出 異蛇 的毒性 為下文 幾死者數矣 作鋪墊 C. 交代以蛇賦稅的背景 引起下文蔣氏有關捕蛇的敘述 2. 本文首段從三方面突出蛇的 異 下列哪一項不屬其中之一 A. 顏色之異 B. 動作之異 C. 毒性之

Microsoft Word - 發布版---規範_全文_.doc

概 述 随 着 中 国 高 等 教 育 数 量 扩 张 目 标 的 逐 步 实 现, 提 高 教 育 质 量 的 重 要 性 日 益 凸 显 发 布 高 校 毕 业 生 就 业 质 量 年 度 报 告, 是 高 等 学 校 建 立 健 全 就 业 状 况 反 馈 机 制 引 导 高 校 优 化 招

鱼类丰产养殖技术(二).doc

疾病诊治实务(一)

名人养生.doc

<4D F736F F D2040B9C5B871A661B0CFABC8AE61C2A7AB55ACE3A8735FA7F5ABD8BFB3B9C5B871A661B0CFABC8AE61C2A7AB55ACE3A8732E646F63>


中老年保健必读(十).doc

27 i

% % ,542 12,336 14,53 16,165 18,934 22,698 25, ,557 7,48 8,877 11, 13,732 17,283 22,

海淀区、房山区(四)

穨ecr1_c.PDF

穨2005_-c.PDF

北京理工大学.doc

尲㐵.⸮⸮⸮⸮⸮

东城区(下)

果树高产栽培技术(一).doc

物质结构_二_.doc

第一節 研究動機與目的

i

水力发电(九)

中国古代文学家(八).doc

景观植物(一)

Microsoft Word - 目录.doc

园林植物卷(三).doc

19q indd

厨房小知识_一_

中南财经大学(七).doc


赵飞燕外传、四美艳史演义

厨房小知识(五)

最新监察执法全书(十八).doc

园林植物卷(十二).doc

华东师范大学.doc

Transcription:

國 立 台 灣 海 洋 大 學 資 訊 工 程 系 C++ 程 式 設 計 期 末 考 參 考 答 案 姓 名 : 系 級 : 學 號 : 97/06/17 考 試 時 間 :10:00 12:10 試 題 敘 述 蠻 多 的, 看 清 楚 題 目 問 什 麼, 針 對 重 點 回 答 是 很 重 要 的 ; 不 確 定 的 請 一 定 要 當 場 提 出 來, 不 要 白 花 力 氣 在 誤 會 我 的 題 意 上, 題 目 敘 述 很 長 的 不 一 定 很 難, 短 的 也 不 一 定 簡 單 ; 總 分 有 178, 超 過 150 的 部 份 不 計 分, 請 看 清 楚 每 一 題 所 佔 的 分 數 再 回 答 考 試 規 則 :1. 不 可 以 翻 閱 課 本, 參 考 書 作 業 及 程 式 2. 不 可 以 使 用 任 何 形 式 的 電 腦 ( 包 含 計 算 機 ) 3. 不 可 以 左 顧 右 盼 不 可 以 交 談 不 可 以 交 換 任 何 資 料 試 卷 題 目 有 任 何 疑 問 請 舉 手 發 問 ( 看 不 懂 題 目 不 見 得 是 你 的 問 題, 有 可 能 是 中 英 文 名 詞 的 問 題 ) 隔 壁 的 答 案 可 能 比 你 的 還 差, 白 卷 通 常 比 錯 得 和 隔 壁 同 學 一 模 一 樣 要 好 很 多 很 多 4. 提 早 繳 卷 同 學 請 直 接 離 開 教 室, 不 得 逗 留 喧 嘩 5. 違 反 上 述 任 何 一 點 之 同 學 一 律 送 請 校 方 處 理 6. 請 在 答 案 卷 上 標 示 題 號 回 答, 繳 卷 時 請 繳 交 簽 名 過 之 試 題 卷 及 答 案 卷 1. a. 請 解 釋 函 式 呼 叫 時 的 繫 結 (binding) 和 函 式 的 連 結 (linking) 有 什 麼 差 別? [5] b. C++ 語 言 中 繫 結 有 動 態 和 靜 態 的 兩 種, 請 說 明 其 語 法 和 工 作 方 式 的 異 同? [10] c. 請 問 為 什 麼 物 件 導 向 概 念 中 希 望 使 用 動 態 繫 結 的 方 式? [5] d. 那 麼 C++ 為 什 麼 還 要 提 供 靜 態 繫 結 的 語 法 呢? [5] a. 繫 結 (binding) 是 指 針 對 程 式 裡 某 一 函 式 呼 叫 敘 述, 如 何 決 定 呼 叫 哪 一 個 函 式 的 機 制 連 結 (linking) 是 指 將 不 同 程 式 模 組 (.cpp,.c,.asm, ) 裡 撰 寫 的 函 式 進 入 點 與 函 式 之 呼 叫 藉 由 函 式 的 名 稱 對 應 起 來, 另 外 程 式 模 組 裏 面 全 域 的 變 數 也 是 藉 由 linker 對 應 起 來, 如 此 在 不 同 檔 案 裡 不 同 的 函 式 可 以 互 相 使 用 b. 靜 態 繫 結 即 為 一 般 程 式 語 言 中 的 函 式 呼 叫,compiler 根 據 function signature 決 定 要 呼 叫 哪 一 個 函 式 ( 全 域 或 是 成 員 函 式 ), 這 是 在 程 式 開 始 執 行 前 就 已 經 確 定 好 了 的 事 情 動 態 繫 結 為 物 件 導 向 程 式 語 言 中 一 般 支 援 的 成 員 函 式 呼 叫 方 法,C++ 語 言 藉 由 function pointer, virtual function 及 virtual function table 來 實 作, 當 透 過 多 型 指 標 呼 叫 某 一 類 別 的 成 員 函 式 時, compiler 將 函 式 呼 叫 換 成 透 過 virtual function table 中 的 function pointer 來 間 接 地 呼 叫 該 成 員 函 式, 因 此 會 在 執 行 時 依 據 物 件 的 種 類 來 呼 叫 正 確 的 成 員 函 式 ( 該 類 別 的 成 員 函 式 ), 兩 者 出 了 都 使 用 函 式 呼 叫 的 形 式 之 外, 運 作 機 制 完 全 不 同 c. 物 件 導 向 中 物 件 接 受 其 它 物 件 的 訊 息 來 運 作, 並 且 針 對 所 接 受 到 的 訊 息 產 生 回 應 的 動 作, 成 員 函 式 所 執 行 的 事 代 表 動 作 的 內 容, 不 論 多 型 指 標 或 是 多 型 參 考 指 向 何 種 類 型 的 物 件, 回 應 應 該 事 由 該 類 別 的 成 員 函 式 來 負 責, 因 此 動 態 繫 結 會 使 得 訊 息 送 到 正 確 的 物 件 去 處 理 d. 基 本 上 C++ 為 了 效 率 考 量 所 以 支 援 靜 態 繫 結 的 機 制, 很 多 類 別 根 本 不 需 要 繼 承 或 是 被 繼 承, 使 用 相 關 物 件 的 成 員 函 式 時 就 可 以 由 Compiler 在 編 譯 時 就 確 定 是 呼 叫 哪 一 個 函 式, 可 以 減 少 函 式 呼 叫 的 額 外 負 擔 (overhead), 物 件 導 向 程 式 中 又 特 別 需 要 許 多 小 成 員 函 式 來 維 持 封 裝 的 功 能, 因 此 C++ 才 特 別 提 供 靜 態 繫 結 的 機 制, 基 本 上 只 要 呼 叫 的 不 是 virtual function, 或 是 並 不 是 透 過 多 型 指 標 或 是 多 型 參 考 來 呼 叫 成 員 函 式,compiler 都 會 用 靜 態 的 細 節 來 實 作 2. a. 請 舉 例 說 明 C++ 中 多 型 (Polymorphism) 有 哪 三 種, 分 別 以 何 種 語 法 完 成? [15] b. 請 問 多 型 對 於 程 式 設 計 者 的 好 處 為 何? [5] c. 請 問 是 哪 一 個 機 制 可 以 達 成 先 編 譯 好 的 程 式 呼 叫 後 撰 寫 的 程 式 (old code call new code)? [5] 1

a. 靜 態 多 型 : function overloading, operator overloading 例 如 : int add(int); double add(double); 動 態 多 型 : virtual function call + inheritance 例 如 : class Basepublic: void service();: class Derived: public Base public: void service();; Derived obj; Base *bptr = &obj; bptr->service(); 參 數 化 多 型 : template function and template class template <class T> template <class T> void swap(t x, T y) class Array T tmp = x; x = y; y = tmp; private: T data[100]; ; b. 可 以 用 單 一 抽 象 的 指 令 來 完 成 各 種 概 念 接 近 的 動 作, 設 計 的 人 不 需 要 仔 細 去 區 分 所 有 不 同 的 狀 況, 可 以 使 得 設 計 起 來 比 較 簡 化 c. 動 態 多 型 : 透 過 多 型 指 標 或 是 多 型 參 考 的 函 式 呼 叫, 可 以 使 得 我 們 在 撰 寫 一 個 類 別 的 程 式 碼 的 時 候 先 根 據 所 需 要 使 用 的 物 件 的 公 開 介 面 來 設 計, 不 需 要 管 實 際 使 用 的 物 件 究 竟 如 何 實 作 該 界 面, 尤 其 是 實 際 使 用 的 物 件 可 能 是 未 來 繼 承 該 介 面 的 類 別 所 產 生 出 來 的 物 件, 此 時 就 發 現 先 編 譯 完 成 的 程 式 碼 是 可 以 和 還 沒 有 寫 出 來 的 程 式 碼 一 起 合 作 的, 我 們 稱 這 種 狀 況 為 old codes call new codes, 相 對 應 於 以 往 在 程 序 化 的 程 式 設 計 裏 面, 你 想 要 使 用 的 函 式 庫 一 定 要 比 你 的 應 用 程 式 先 寫 好, 有 這 種 機 制 以 後 程 式 的 彈 性 會 變 得 大 的 多 3. a. 請 舉 例 說 明 什 麼 叫 做 初 始 化 串 列 (initialization list)? [5] b. 請 問 初 始 化 串 列 中 初 始 化 多 個 資 料 成 員 時 的 執 行 順 序 為 何? [5] c. 請 問 沒 有 在 初 始 化 串 列 中 出 現 的 資 料 成 員 compiler 會 做 什 麼 處 理? [5] d. 請 列 舉 不 用 初 始 化 串 列 就 無 法 完 成 初 始 化 的 情 況? [10] a. class A public: A(): m_y(0), m_x(1) private: int m_x; int m_y; ; b. 執 行 順 序 並 非 在 初 始 化 序 列 中 撰 寫 的 順 序, 以 上 例 來 說, 並 非 先 設 定 m_y 為 0, 再 設 定 m_x 為 1, 而 是 依 照 資 料 成 員 m_x, m_y 在 類 別 宣 告 裏 面 定 義 的 順 序 來 執 行, 也 就 是 先 m_x 再 m_y c. 如 果 是 父 類 別 物 件 或 是 物 件 成 員,compiler 會 自 動 使 用 default ctor 來 初 始 化, 但 是 如 果 是 基 礎 型 態 int, int*, double, char 等 等 則 compiler 不 做 任 何 額 外 的 動 作 2

d. i. 使 用 有 參 數 的 父 類 別 建 構 元 建 構 父 類 別 物 件 時 ii. 使 用 有 參 數 的 建 構 元 建 構 物 件 成 員 時 iii. 初 始 化 類 別 裡 定 義 的 常 數 資 料 成 員 時 iv. 初 始 化 類 別 裡 定 義 的 參 考 型 態 資 料 成 員 時 v. 多 重 繼 承 時 virtual base class 裏 面 成 員 的 初 始 化 時 以 上 這 五 個 地 方 是 你 一 定 要 使 用 初 始 化 串 列 的 地 方, 也 許 有 時 ( 運 氣 好 ) 可 以 有 替 代 的 方 法, 但 是 大 概 都 伴 隨 著 比 較 差 的 效 率 或 是 多 做 了 許 多 額 外 的 事, 不 如 使 用 初 始 化 串 列 來 得 簡 潔 4. 參 考 下 圖 中 程 式 片 段 回 答 相 關 問 題 1. class Scores 2. 3. public: 4. Scores(); 5. virtual ~Scores(); 6. private: 7. int *m_scores; 8. ; 9. 10. Scores::Scores() 11. 12. m_scores = new int[5]; 13. for (int i=0; i<5; i++) 14. m_scores[i] = 0; 15. 16. Scores::~Scores() 17. 18. delete [] m_scores; 19. 20. void init(scores &score) 21. 22. Scores tmp; 23. score = tmp; 24. 25. int main() 26. 27. Scores myscores; 28. 29. init(myscores); 30. 31. a. 程 式 執 行 時 發 現 main() 函 式 中 的 myscores 這 個 物 件 裡 的 資 料 會 不 斷 地 自 己 更 改, 明 明 沒 有 修 改 它 的 資 料, 但 是 資 料 卻 隨 著 程 式 執 行 到 不 同 地 方 而 不 斷 地 改 變, 請 解 釋 其 發 生 之 原 因? [10] b. 請 說 明 該 如 何 藉 由 增 加 一 個 Scores 類 別 的 成 員 函 式 來 避 免 這 個 錯 誤? [10] a. 主 要 原 因 是 第 23 列 score = tmp; 時 因 為 Scores 類 別 沒 有 定 義 Big 3 中 的 assignment operator 而 在 第 24 列 又 自 動 解 構 tmp.m_scores, 因 此 score 物 件 裡 指 到 的 m_scores 其 實 是 已 經 歸 還 給 系 統 的 記 憶 體 區 塊, 系 統 會 把 這 塊 記 憶 體 給 任 何 其 他 配 置 敘 述 拿 去 使 用, 於 是 別 部 份 的 程 式 在 修 改 資 料 時,score 就 會 發 現 自 己 的 資 料 莫 名 奇 妙 地 在 變 動 著, 如 下 圖 : score tmp m_scores m_scores other references memory leakage b. 實 作 Scores::operator=(Scores &) 成 員 函 式 Scores &Scores::operator=(Scores &rhs) if (&rhs = = this) return *this; // delete [] m_scores; // m_scores = new int[5]; for (int i = 0; i<5; i++) 3 released memory block

m_scores[i] = rhs.m_scores[i]; return *this; 5. 下 圖 是 一 個 mp3 播 放 程 式 的 操 作 按 鍵, 其 基 本 動 作 說 明 如 下 i. 系 統 在 暫 停 或 是 停 止 狀 態 下, 按 下 play 按 鍵 可 以 繼 續 / 開 始 播 放 ii. 系 統 在 暫 停 狀 況 下, 按 下 pause 按 鍵 可 以 繼 續 播 放 iii. 系 統 在 暫 停 或 是 播 放 狀 況 下, 按 下 stop 按 鍵 可 以 停 止 播 放 vi. 系 統 在 播 放 狀 況 下, 按 下 pause 按 鍵 可 以 暫 停 播 放 假 設 已 經 寫 好 了 do_play(startingsecond), do_stop(), do_pause(pausedposition) 這 三 個 底 層 操 作 聲 音 界 面 和 媒 體 檔 案 的 函 式 供 你 使 用, 請 注 意 你 不 需 要 寫 顯 示 圖 形 或 是 當 使 用 者 用 滑 鼠 按 下 按 鈕 時 的 動 作, 這 些 都 假 設 已 經 寫 好 了 a. 請 分 析 系 統 所 有 可 能 接 受 到 的 訊 息? [3] b. 請 畫 一 個 狀 態 圖 說 明 上 述 運 作 狀 態? [12] c. 請 實 作 一 個 單 一 狀 態 變 數, 並 且 實 作 mp3player 類 別 的 三 個 界 面 函 式 [9]? a. 至 少 有 play, pause, and stop 三 種 使 用 者 透 過 界 面 送 近 來 的 訊 息, 可 能 還 有 播 放 完 畢 的 訊 息, 或 是 播 放 進 度 的 訊 息, 後 兩 者 和 底 層 多 媒 體 播 放 API 有 關 係 b. 我 們 以 三 種 使 用 者 操 作 界 面 的 訊 息 為 主 繪 製 其 狀 態 圖 (state diagram) play/do_play(0) play/nop stop, pause/ NOP STOPPED stop/do_stop() PLAYING play,pause/ do_play(m_currentposition) pause/do_pause() PAUSED stop/do_stop() c. class mp3player public: enum State PLAYING, STOPPED, PAUSED; mp3player(); void play(); 4

void stop(); void pause(); private: State m_state; int m_currentposition; ; mp3player::mp3player():m_state(stopped), m_currentposition(0) void mp3player::play() if (m_state == STOPPED) m_currentposition = 0; do_play(0); m_state = PLAYING; else if (m_state == PAUSED) do_play(m_currentposition); m_state = PLAYING; else if (m_state == PLAYING); void mp3player::stop() if ((m_state == PLAYING) (m_state == PAUSED)) m_currentposition = 0; do_stop(); m_state == STOPPED; else if (m_state == STOPPED); void mp3player::pause() if (m_state == PLAYING) m_currentposition = do_pause(); m_state = PAUSED; else if (m_state == PAUSED) do_play(m_currentposition); m_state = PLAYING; else if (m_state == STOPPED); 以 上 程 式 其 實 有 一 些 假 設, 例 如 do_pause() 會 回 傳 目 前 播 放 的 位 置 6. a. 請 問 C++ 用 什 麼 語 法 實 現 Generic Programming? [5] b. 請 將 右 圖 中 的 函 式 轉 為 一 個 樣 版 函 式? [5] c. 請 定 義 一 個 C++ 類 別 MyType 使 得 下 面 的 程 式 碼 能 夠 配 合 題 b. 中 的 樣 版 函 式 sum 運 作? [10] MyType<int> s1, s2; MyType<int> s3 = sum(s1, s2, s2); a. template function 及 template class, 亦 即 parameterized polymorphism b. template <class T> T sum(t a, T b, T c) 5 1. int sum(int a, int b, int c) 2. 3. return a + b + c; 4.

return a + b + c; c. template <class T> class MyType public: MyType(); MyType operator+(mytype &); private: T m_data[10]; ; template <class T> MyType<T>::MyType() for (int i=0; i<10; i++) m_data[i] = T(0); template <class T> MyType<T> MyType<T>::operator+(MyType<T> &rhs) MyType<T> tmp = *this; for (int i=0; i<10; i++) tmp.m_data[i] += rhs.m_data[i]; return tmp; 這 個 類 別 必 須 設 計 operator+() 否 則 題 b. 中 的 a+b+c 無 法 運 作, 另 外 由 於 這 個 類 別 沒 有 自 行 配 置 記 憶 體, 所 以 可 以 用 預 設 的 拷 貝 建 構 元 處 理 tmp = *this; 另 外 由 於 平 常 operator+() 都 是 沒 有 side effect 的, 不 可 以 在 加 的 時 候 改 掉 物 件 的 內 容, 所 以 另 外 配 置 一 個 暫 時 的 變 數 tmp 7. 參 考 下 列 的 程 式 片 段 回 答 相 關 問 題 1. #include <iostream> 2. using namespace std; 3. class Fruit 4. 5. public: 6. virtual void printclassname() = 0; 7. virtual ~Fruit() 8. ; 9. class Apple : public Fruit 10. 11. public: 12. void printclassname() 13. 14. cout << "Apple" << endl; 15. 16. ; 17. class Pear : public Fruit 18. 19. public: 20. void printclassname() 21. 22. cout << "Pear" << endl; 23. 24. ; 25. 26. class Full ; 27. class Empty ; 28. 29. class BagOfFruit 30. 31. public: 32. BagOfFruit() : m_numelems(0) 33. unsigned int numelems() const 34. 35. return m_numelems; 36. 37. virtual void insert(fruit &f) throw(full); 38. virtual Fruit &remove() throw(empty); 39. private: 40. enum NumMaxElems = 20 ; 41. unsigned int m_numelems; 42. Fruit *m_data[nummaxelems]; 43. ; a. [10] 請 完 成 類 別 BagOfFruit 的 製 作 :BagOfFruit 類 別 是 一 個 藉 由 父 類 別 指 標 ( 此 處 指 的 是 Fruit 類 別 物 件 的 指 標 ) 來 操 作 的 異 質 容 器 類 別, 在 一 袋 水 果 中 最 多 可 以 存 放 20 (NumMaxElems) 個 各 式 的 水 果 ( 由 Fruit 類 別 衍 生 出 來 的 類 別 ), 類 別 資 料 成 員 m_numelems 記 錄 袋 中 共 有 多 少 個 水 果 物 件, 注 意 這 個 數 字 必 須 保 證 在 0 到 NumMaxElems-1 之 間,m_data 這 個 Fruit * 型 態 6

的 指 標 陣 列 是 用 來 記 住 袋 中 有 哪 些 物 件 的, 請 完 成 insert() 及 remove() 函 式 的 製 作, 其 中 insert 函 式 可 以 將 一 個 Fruit 類 別 的 物 件 記 錄 在 m_data 陣 列 中 ( 應 該 說 是 將 一 個 水 果 置 入 袋 中 ), 如 果 不 幸 insert 動 作 失 敗 的 時 候, 請 依 照 類 別 宣 告 中 的 exception specifier 丟 出 適 當 的 例 外 事 件, remove 則 是 把 放 在 最 上 面 的 水 果 ( 最 後 放 進 去 的 水 果 ) 取 出 來, 在 BagOfFruit 物 件 中 就 不 記 錄 這 個 被 取 出 的 物 件 了, 同 樣 地 在 發 生 remove 錯 誤 時 也 請 產 生 例 外 物 件 void BagOfFruit::insert(Fruit &f) throw(full) if (m_numelems >= NumMaxElems) throw Full(); m_data[++m_numelems] = &f; Fruit &BagOfFruit::remove() throw(empty) if (m_numelems <= 0) throw Empty(); return *m_data[m_numelems--]; b. [10] 請 撰 寫 一 小 段 程 式, 產 生 11 個 Apple 類 別 的 物 件 及 11 個 Pear 類 別 的 物 件, 然 後 交 替 地 放 入 一 個 BagOfFruit 類 別 的 物 件 中, 記 得 處 理 例 外 狀 況 BagOfFruit bof; Apple *aptr = 0; Pear *pptr = 0; try for (int i=0; i<11; i++) aptr = new Apple(); bof.insert(*aptr); pptr = new Pear(); bof.insert(*pptr); catch (Full &e) cout << "Bag full\n"; catch (Empty &e) cout << "Bag empty\n"; 7

c. [4] 假 設 在 系 統 中 需 要 一 種 BagOfApple 的 物 件, 這 種 物 件 只 能 放 入 Apple 類 別 的 物 件, 這 種 物 件 提 供 的 界 面 包 括 unsigned int numelems() const; void insert(apple&a) throw(full); 及 Apple &remove() throw(empty); 因 為 這 個 界 面 和 BagOfFruit 實 在 很 接 近, 因 此 某 甲 就 運 用 繼 承 的 語 法 製 作 了 下 面 的 類 別 1. class BagOfApple : public BagOfFruit 2. 3. public: 4. BagOfApple() : BagOfFruit() 5. void insert(apple &a) throw(full) 6. 7. BagOfFruit::insert(a); 8. 9. Apple &remove() throw(empty) 10. 11. return (Apple &)BagOfFruit::remove(); 12. 13. ; 請 問 下 面 的 程 式 碼 中 第 4 列 在 執 行 時 會 呼 叫 哪 一 個 函 式? 第 5 列 在 執 行 時 會 呼 叫 哪 一 個 函 式? 1. BagOfApple boa; 2. BagOfFruit *pbof = &boa; 3. Apple a; 4. pbof->insert(a); 5. pbof->remove(); (1) 請 注 意 第 5 列 到 第 8 列 void &BagOfApple::insert(Apple &) 並 沒 有 覆 寫 (override) void &BagOfFruit::insert(Fruit &), 因 為 參 數 的 型 態 是 不 一 樣 的, 基 本 上 只 是 hide 父 類 別 的 同 名 函 式 而 已 (2) 請 注 意 第 9 列 到 第 12 列 運 用 到 所 謂 的 Contravariance 的 概 念, 很 多 編 譯 器 (VC 6.0) 並 不 支 援, VC 6 在 編 譯 的 時 候 會 告 訴 你 Apple &BagOfApple::remove() 嘗 試 覆 寫 Fruit &BagOfFruit::remove() 函 式, 而 且 兩 個 函 式 只 有 回 傳 值 是 不 一 樣 的, 這 是 不 允 許 的 ; 相 反 地, 在 Linux 上 的 GNU g++ 就 允 許 這 個 語 法, 讓 Apple &BagOfApple::remove() 覆 寫 Fruit &BagOfFruit::remove() 函 式, 以 g++ 為 例 : 第 4 列 呼 叫 BagOfFruit::insert(Fruit &) 第 5 列 呼 叫 BagOfApple::remove() d. [4] 假 設 在 BagOfFruit 的 定 義 中 ( 第 37, 38 列 ), insert() 及 remove() 函 式 並 不 是 虛 擬 函 式 (virtual function) 請 問 上 圖 中 第 4 列 及 第 5 列 會 呼 叫 哪 一 個 函 式? 第 4 列 呼 叫 BagOfFruit::insert(Fruit &) 第 5 列 呼 叫 BagOfFruit::remove() e. [6] 請 閱 讀 下 圖 程 式, 說 明 第 11 列 中 compiler 會 自 動 將 物 件 p 做 什 麼 樣 的 型 態 轉 換? 請 問 第 12 列 會 印 出 什 麼 信 息? Pear 類 別 的 物 件 到 底 可 不 可 以 置 入 BagOfApple 類 別 的 容 器 物 件 中 呢? 1. void insertfruit(bagoffruit &bag, Fruit &f) 2. 3. bag.insert(f); 4. 5.... 6. void main() 7. 8.... 9. BagOfApple boa; 10. Pear p; 8 11. insertfruit(boa, p); 12. boa.remove().printclassname(); 13.

Pear 型 態 的 物 件 先 轉 換 成 Fruit 物 件 的 參 考, 會 印 出 Pear 目 前 程 式 可 以 將 Pear 物 件 置 入 BagOfApple 容 器 物 件 中 而 且 在 第 3 列 是 呼 叫 BagOfFruit::insert(Fruit &) 而 不 是 BagOfApple::insert(Apple &) f. [5] 請 問 像 insertfruit() 這 樣 子 一 個 基 於 基 礎 類 別 BagOfFruit 和 Fruit 的 定 義 所 寫 出 來 的 函 式 是 否 可 以 處 理 衍 生 類 別 BagOfApple 的 物 件 呢? ( 為 什 麼?) 實 際 運 作 中 你 會 發 現 在 insertfruit() 函 式 中, 並 無 法 正 確 地 將 Apple 物 件 insert 到 BagOfApple 中, 除 非 運 用 downcast 將 第 三 列 改 成 bag.insert((apple) f); 但 是 這 樣 又 沒 有 辦 法 處 理 一 般 的 BagOfFruit 物 件, 所 以 基 本 上 這 個 設 計 是 不 理 想 的, 應 該 用 組 合 來 重 新 設 計 BagOfApple 類 別 9