一、 錯誤現場
// 基類 (MFC CFrameWnd)
virtual BOOL OnCreateClient(LPCREATESTRUCT, CCreateContext*);
// 衍生類
virtual bool OnCreateClient(LPCREATESTRUCT, CCreateContext*); // 錯誤:bool vs BOOL
// 編譯錯誤 C2555: 虛函式回傳型別不同
// 'CMainFrame::OnCreateClient' : overriding virtual function differs from
// 'CFrameWnd::OnCreateClient' only by return type
二、 根因:兩個完全不同的型別
| 特性 | BOOL (Windows/MFC) | bool (C++ 標準) |
| 定義 | typedef int BOOL; (windef.h) | 內建關鍵字 (C++98 / C99 _Bool) |
| 大小 | 4 位元組 (int) | 1 位元組 |
| 值域 | 任意 int (通常 0/非零) | true (1) / false (0) |
| 型別安全 | 弱 (可隱式轉換任意整數) | 強 (不可隱式轉換整數) |
| 標頭檔 | <windows.h>, <windef.h> | <cstddef> / 關鍵字 |
三、 導致覆寫失敗的機制
- C++ 覆寫要求回傳型別協變 (Covariant Return Type) 或完全相同。
BOOL (int) 與 bool 大小、表示法、型別系統皆不同,非協變關係。
- 編譯器視為「同名函式回傳型別衝突」而非合法覆寫,報錯 C2555。
四、 常見踩坑場景
- MFC/ATL/Windows API 回呼:基類用
BOOL,衍生類習慣寫 bool。
- 跨 DLL 介面:一方用
BOOL,另一方用 bool,二進制介面 (ABI) 不相容。
- 混合 C/C++ 編譯:C 用
int 模擬布林,C++ 用 bool,透過 extern "C" 傳遞。
五、 修正策略
- 統一用 BOOL:實作 Windows/MFC 介面時,嚴格遵循基類簽名 (
BOOL, HRESULT, LRESULT 等 Windows 型別)。
- 內部邏輯用 bool:類內部私有函式、純 C++ 邏輯優先用
bool,介面層轉換:
BOOL Wrapper() { return InternalLogic() ? TRUE : FALSE; }
- static_cast 明確轉換:
return static_cast(condition); 避免隱式轉換警告。
六、 跨平台型別對照表 (Windows vs 標準 C/C++)