iT邦幫忙

2025 iThome 鐵人賽

DAY 9
2
Software Development

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

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

  • 分享至 

  • xImage
  •  

又閱讀了兩個章節之後,到了愉快的考試時間!分享一件有趣的事情:在這次的考題中,AI 居然給出了錯誤的解答。看來除了靠科技輔助,識別對錯的學習能力依然重要呢。

Chapter 3. Resource Management

Q1. 以下是一個使用 factory function 來建立 YoyoFamily 物件的函式:

void f()
{
    YoyoFamily* pInv = createYoyoFamily();
    // use pInv here...
    delete pInv;
}

這種資源管理方式的主要問題是什麼?
A) 在 C++ 中無法使用指標搭配工廠函式。
B) 此程式碼無法編譯,因為 delete 不能用在指標上。
C) 在某些情境下資源將無法釋放,導致記憶體洩漏。
D) delete 只能用於陣列,不能用於單一物件。
E) 在刪除指標時,函式將永遠拋出 exception。

如果在執行到 delete 之前,函式因為 return、exception 或其他控制流程而提早結束,那麼動態配置的資源就無法被釋放,從而造成記憶體洩漏。

這是一個典型的資源管理問題,通常會透過 RAII 來解決。透過物件的生命週期來管理資源,確保資源在離開作用域時自動釋放。

Q2. 比直接在函式呼叫中傳遞 new Widget,為何更推薦以下程式碼的寫法?

std::tr1::shared_ptr<Widget> pw(new Widget);
processWidget(pw, priority());

A) 讓程式碼更加精簡,增加可讀性。
B) 可以將 raw pointer 自動轉換成 shared_ptr 等智慧指標。
C) 在進行可能會丟出 exception 的其他操作之前,能避免資源洩漏。
D) 避免使用動態記憶體配置。
E) 保證 priority() 一定會先被呼叫。

在獨立的程式碼中先使用 shared_ptr 等智慧指標來儲存 new 配置的物件,可以確保這個資源在進行其他可能會丟出 exception 的操作之前,已經被妥善管理。這樣就能有效避免資源洩漏的問題,是 C++ 中良好的 exception safety 實作方式之一。

知識點 17 中曾經提到過,函式參數的求值順序是未定義的。以這題來說,priority() 可能會在 shared_ptr 建構之前執行。然而自 C++ 17 之後的版本,函式呼叫參數的求值順序已明確定義為從左至右。只是為了保險起見,仍建議將資源管理與其他操作分開寫。

Chapter 4. Designs and Declarations

Q1. 為什麼在一個 type-safe 的 Month 類別中表示特定月份,使用像是 Month::Jan() 的函式會比靜態物件 Month::January 更好?
A) 函式比物件執行得更快。
B) 非區域靜態物件的初始化可能會有問題。
C) 函式都允許隱式轉換,可提升程式碼的可讀性。
D) 在 C++ 中,enum 永遠是 type-safe 的。
E) 因為物件不能用作函式引數。

使用像是 Month::Jan() 的函式可以避免在 C++ 中與初始化順序相關的異常,這確保了 Month 物件在需要時能夠可靠地建構。

在 C++ 中,全域變數靜態變數靜態物件會在程式啟動時初始化,並在結束時銷毀。靜態物件的初始化順序是有規範的,但這個順序對於不同的 translation unit 是未定義的。這可能導致某些靜態物件未按預期的順序被初始化,尤其是在複數檔案之間依賴靜態物件時更為嚴重。

Q2. 為什麼即使在兩者提供相同功能時,C++ 仍然偏好使用非成員非友元函式而不是成員函式?
A) 非成員非友元函式能增加封裝性。
B) 非成員函式比成員函式執行得更快。
C) 非成員函式只能在全域範圍內定義。
D) 成員函式無法呼叫其他成員函式。
E) 非成員函式會自動成為類別的友元。

非成員非友元函式無法訪問類別的私有成員,因此不會降低封裝性。而成員函式可以訪問所有的私有成員,即使是新增的成員函式依舊能訪問私有資料。非成員函式可以定義在 namespace 中,且不會被預設為友元。成員函式之間則可以相互呼叫。

「友元」就是知識點 24 所說的 friend。這是 C++ 的一個特殊概念,允許特定的函式、類別或方法訪問另一個類別的私有成員和保護成員。通常,私有成員和保護成員是類別內部使用的,不會對外暴露。但透過將其他類別或函式設為友元可以突破封裝性。


上一篇
[Day 8] Design and Declarations II
下一篇
[Day 10] Implementations I
系列文
30 天 Effective C++ 大挑戰!!30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言