今天的題目雖然相對簡單一些,但涵蓋了物件導向設計的核心觀念,仍然非常值得深入探討。這些底層邏輯不僅是優化 C++ 程式的根基,更是在面對複雜系統設計時不可或缺的知識!
Q1. 以下哪一個敘述最能描述 Person
和 Student
在公共繼承中的關係?
class Student { ... };
class Yoyo : public Student { ... };
A) 每個 Student
都是 Yoyo
,但不是每個 Yoyo
都是 Student
。
B) Student
和 Yoyo
毫無關聯。
C) Yoyo
和 Student
在所有情況下都可以互換。
D) 每個 Yoyo
都是 Student
,但不是每個 Student
都是 Yoyo
。
E) Yoyo
是一個比 Student
更抽象的實作類別。
「公共繼承」表達的是「is-a」關係,這表示
Yoyo
是Student
。
將 Yoyo
當成 Student
使用稱為「向上轉型」,反之則為「向下轉型」。向下轉型可能導致未定義行為或運行時錯誤,特別是在不安全的型別轉換時需小心使用。
Q2. 在 C++ 中,為什麼重新定義從基底類別繼承來的非虛擬函式會造成問題?
A) 行為不一致難以預料。
B) 會造成編譯錯誤。
C) 非虛擬函式無法被繼承。
D) 這種行為會自動把函式變成虛擬的。
E) 因為這會阻止呼叫基底類別的函式。
非虛擬函式呼叫時根據靜態型別決定,不具多型特性。根據所使用的指標或參考的靜態型別,會造成行為不一致。
若在子類別中重新定義了一個非虛擬函式,實際執行時會根據變數的靜態型別來決定呼叫哪個函式,而不是物件的實際動態型別。重定義非虛擬函式可能造成錯誤或非預期的行為,若需要支援「多型」應使用 virtual
。
Q3. 何時應該使用 Composition 而非 Public Inheritance?
A) 當想要將所有基底類別的方法公開。
B) 當只想覆寫基底類別的部分方法。
C) 當類別之間是「has-a」或「實作上使用」,而不是「is-a」的關係。
D) 當想使用支援多型的虛擬函式。
E) 當要描述的關係不是「is-a」,而是像實作細節或內部包含關係。
若某個類別並非另一個類別的延伸,這時應該使用「組合」而非「繼承」。
組合提供更好的封裝與靈活性,減少耦合不會導致繼承的複雜性。
Q4. 以下關於「虛擬繼承」的描述何者正確?
A) 在公開繼承中,虛擬繼承總是比非虛擬繼承好。
B) 虛擬繼承可能增加物件大小並降低成員存取效能。
C) 虛擬繼承只能用在私有繼承中。
D) 使用虛擬繼承時,不需要初始化基底類別。
E) 所有介面類別都必須使用虛擬繼承。
虛擬繼承可解決多重繼承中的菱形繼承問題,但會增加物件的大小與執行時開銷。
虛擬繼承主要是為了解決菱形繼承,可避免虛擬基底類別多重繼承造成的重複成員問題。但它會引入額外的記憶體與運算負擔,因此不建議做為預設使用的工具。