iT邦幫忙

2025 iThome 鐵人賽

DAY 5
1
Software Development

30 天 Effective C++ 大挑戰!!系列 第 5

[Day 5] 中場休息 Q&A小測驗!!

  • 分享至 

  • xImage
  •  

一口氣讀完了兩個章節,是否開始感到混亂了呢?感謝這個科技的時代,可以請 AI 協助出題複習知識點,並精選重要概念做個階段性的檢核。讓我們一起溫故而知新,針對不熟悉的觀念查缺補漏吧!

Chapter 1. Accustoming yourself to C++

Q1. 在使用 STL 的 iterator 和 function object 時,通常會用哪種方式傳遞參數?
A) Pass-by-reference-to-const。
B) Pass-by-pointer。
C) Pass-by-reference。
D) Pass-by-move。
E) Pass-by-value。

在 STL 中,iterator 和 function object 的設計是基於 C 語言的指標,因此依然適用 pass-by-value 規則。這種方式可有效提高安全性,避免因指標或引用錯誤造成原始物件被修改。

STL 是 C++ 的重要工具,由 container、iterator、algorithm、function object 組成。Iterator 用來指向 container 內的元素,並提供遍歷這些元素的功能。Function object 也稱為 functor,允許我們像函式那樣操作物件。

對於 container 等較大型的物件,則通常會選擇 pass-by-reference 的方式,確保程式的性能。

Q2. 在某些編譯器上,以下這段程式碼可能無法編譯:

class StudentYoyo {
private:
    static const int subject = 5;
    int scores[subject];
};

如何確保 subject 作為 array size 能在所有編譯器上正確運作?
A) 宣告 subject 為 non-static 成員。
B) 使用 #define 定義 subject
C) 將 subject 改為非 const 的靜態成員。
D) 在 class 內使用 enum { subject = 5 };
E) 將 subject 宣告為 extern

enum 是一種廣泛的解法,能確保陣列大小設定等常數可在編譯時使用,並能適用於所有編譯器。

在 C++ 中,陣列的大小必須是 compile-time constant。在此題 subject 被宣告為 static const 成員。雖然理論上是一個常數,然而某些舊式編譯器無法正常處理。

enum 仍作用於 class 內部,不會污染到其他 namespace。這種技術被稱為 Enum Hack。

Non-static 成員的值必須依賴 object 的實例,無法在編譯時確定,因此不適合用於陣列大小。使用 #define 可以提供 compile-time constant,但會污染 namespaceextern 表示變數是外部的,通常需在執行時決定其值。

Chapter 2. Constructors, Destructors, and Assignment Operators

Q1. 關於 copy assignment operator 呼叫 copy constructor,下列敘述何者正確?
A) 這類做法可以有效避免程式碼重複。
B) 有可能會造成異常,應避免這種情境。
C) 這是 C 語言白皮書強烈推薦的寫法。
D) 只有包含簡單資料成員的 class 才可以這麼做。
E) 是可以確保 exception-safe 的唯一方法。

copy assignment operator 和 copy constructor 的語意不同,這樣做可能會導致物件出現不正確或未定義的行為。

知識點 5知識點 12 都有強調過,copy constructor 會先建立一個全新的 object,copy assignment operator 則用於將來源物件的狀態賦值給一個已存在的 object。

Q2. 以下類別中,針對解構子內的 close() 函式可能拋出的 exception,應採用何種處理方式?

class DBConn {
public:
    ~DBConn() { db.close(); }
private:
    DBConnection db;
};

A) 讓 exception 自然地從解構子傳播出去。
B) 忽略 exception 的可能性,因為解構子不應該失敗。
C) 以 static 變數追蹤 exception。
D) 選擇吞下 exception 或終止程式。
E) 增加 throw() 規範來宣告解構子。

解構子應該捕捉由 close() 函式拋出的 exception,有幾種常見的處理方式:

  • 吞下 exception。 e.g. 記錄錯誤
  • 主動終止程式。 e.g. 調用 std::abort

解構子通常在 object 範圍結束或因 exception 而進行 stack unwinding 時被調用。此時程式已進入清理階段,解構子拋出 exception 可能會導致資源泄漏。若在 stack unwinding 期間重複拋出 exception,程式可能會因同時有多個 exception 而導致而強制 std::terminate

現代 C++ 不建議使用 throw() 的方式,且無法完全避免解構子拋 exception 的問題。


上一篇
[Day 4] Constructors, Destructors, and Assignment Operators II
下一篇
[Day 6] Resource Management
系列文
30 天 Effective C++ 大挑戰!!30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言