國家安全情報人員考試五等考試-資訊組資料處理大意104 年第 7 題單選題
根據下列的 C++語言程式碼,請問輸出結果為何?
#include <iostream>
using namespace std;
class CPet
{
public:
void Show() { cout << "Pet"; }
};
class CDog : public CPet
{
public:
virtual void Show() { cout << "Dog"; }
};
class CSmallDog : public CDog
{
public:
void Show() { cout << "SmallDog"; }
};
int main()
{
CPet aPet;
CDog aDog;
CSmallDog aSmallDog;
CPet* pPet[3] = { &aPet, &aDog, &aSmallDog};
for (int i=0; i<3; i++)
pPet[i]->Show();
return 0;
}
APet Dog SmallDog
BPet Pet Pet正確答案
CPet Dog Dog
DPet SmallDog SmallDog
B正確答案
基底類別 CPet 的 Show() 非 virtual,透過 CPet* 指標呼叫時採靜態繫結,三次都輸出 Pet。
為什麼答案是 B
CPet::Show() 非 virtual,透過 CPet* 指標呼叫時採靜態繫結,直接呼叫 CPet::Show(),三個元素皆輸出 Pet。CDog 後來加 virtual 對基底無效。
載入中…
完整詳解
Pro · 無限重點 基底類別 CPet 的 Show() 非 virtual,透過 CPet* 指標呼叫時採靜態繫結,三次都輸出 Pet。
看「最上層基底」有沒有 virtual:沒有就走靜態繫結,指標型別決定呼叫哪個函式。
逐選項分析
A✕ 陷阱
這是「若 CPet::Show() 有 virtual」才會出現的多型結果。但題目中 CPet::Show() 沒宣告 virtual,所以不會動態分派。最常見陷阱。
B✓ 正確
CPet::Show() 非 virtual,透過 CPet* 指標呼叫時採靜態繫結,直接呼叫 CPet::Show(),三個元素皆輸出 Pet。CDog 後來加 virtual 對基底無效。
C✕
即使 virtual 從 CDog 開始生效,也無法讓 CPet* 指標觸發多型,因為 virtual 必須在「呼叫時的指標型別」那層宣告才有效。
D✕
要輸出 SmallDog 必須整條繼承鏈都 virtual 且透過基底指標呼叫。本題基底非 virtual,靜態繫結只會看指標型別 CPet*。
C++ 多型關鍵:virtual 要在「基底」就宣告
| 基底函式 | 呼叫方式 | 繫結時機 | 結果 |
|---|
| 非 virtual | 基底指標/參考 | 編譯期 (靜態) | 看指標型別 → 呼叫基底版本 |
| virtual | 基底指標/參考 | 執行期 (動態) | 看實際物件 → 呼叫最衍生版本 |
| 任何情況 | 物件本身 (非指標) | 編譯期 | 看物件型別 |
題目故意在 CDog 才加 virtual,誘導考生以為會多型。但 C++ 的 virtual 必須在「呼叫時所用的指標/參考型別」那層就宣告才有效。用 CPet* 呼叫時,編譯器只看 CPet 有沒有 virtual——沒有就走靜態繫結。