首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 核心特性深度解析:繼承、多態與異常處理

     編輯:關於C++

面向對象程式設計:繼承機制詳解

繼承是 C++ 實現程式碼重用的核心機制之一。當定義新類別時,若想重用既有類別的功能,即可透過繼承實現。語法形式為 class NewClass : public OldClass { /* 新增成員 */ };。子類別將繼承父類別的所有成員(包含私有、保護、公開),但私有成員在子類別中無法直接存取。繼承方式分為 public、private、protected 三種,實務上以 public 最為常見,因能保持成員原有的存取層級。

繼承的關鍵特性

  • 建構與解構順序:建構子優先呼叫父類別建構子,再依宣告順序初始化成員物件,最後執行自身建構子本體。解構順序恰好相反。若父類別建構子需參數,必須在子類別初始化清單中以父類別名稱指定。
  • 成員函式隱藏:子類別定義的同名函式會隱藏父類別的所有同名函式(無論參數表是否相同),不構成多載。若需呼叫父類別版本,必須以 BaseClass::func() 明確指定。
  • 多重繼承:一個類別可繼承多個父類別,各父類別可指定不同繼承方式。建構子呼叫順序依繼承宣告順序,與初始化清單順序無關。
  • 虛擬繼承:解決鑽石繼承問題。當多條繼承路徑指向同一基底類別時,在中間類別繼承時加上 virtual 關鍵字,可確保最終衍生類別僅保留一份虛擬基底類別的成員。虛擬基底類別的建構子由最底層的衍生類別直接初始化。

多態:動態綁定的核心機制

多態指「一個介面,多種實現」。透過基底類別指標或參考指向衍生類別物件,呼叫虛擬函式時,系統依物件實際類型決定呼叫哪個版本,實現執行期綁定。

虛擬函式與虛擬函式表

以 virtual 宣告的函式為虛擬函式。編譯器為每個含虛擬函式的類別建立虛擬函式表(vtable),儲存虛擬函式位址。每個物件內含一指標(vptr)指向其類別的 vtable,使物件大小增加 4 位元組(32 位元系統)。衍生類別覆寫虛擬函式時,函式名稱、參數表、回傳型別必須一致(回傳型別允許共變)。

執行期型別識別(RTTI)

  • dynamic_cast:安全向下轉型。dynamic_cast<Derived*>(base_ptr) 成功回傳衍生類別指標,失敗回傳 nullptr;參考版本失敗拋出 bad_cast 異常。要求類別具有虛擬函式。
  • typeid:回傳 type_info 參考,可比較型別相等性,name() 回傳型別名稱(編譯器相依)。若類別有虛擬函式,typeid 亦利用多態識別動態型別。

純虛擬函式與抽象類別

以 = 0 取代函式本體的虛擬函式稱為純虛擬函式。含純虛擬函式的類別為抽象類別,無法直接實例化物件,僅能作為基底類別,由衍生類別實作純虛擬函式後才能建立物件。利用多態時,必須透過基底類別指標或參考操作衍生類別物件,而非建立基底類別物件。

虛擬解構子

透過基底類別指標 delete 衍生類別物件時,若基底類別解構子非虛擬,僅呼叫基底解構子導致資源洩漏。故基底類別解構子應宣告為 virtual,確保正確呼叫衍生類別解構子。解構子可為純虛擬,但必須提供定義;建構子不可為虛擬。

標準字串類別 std::string

定義於 <string>,提供豐富操作介面:

  • 建構:string(const string&)、string(const char*)、string(size_t n, char c)。
  • 運算子:<<、>>、=、+、+=、[]、at()、比較運算子。
  • 長度與容量:size()、length()、empty()、resize()。
  • C 風格轉換:c_str()(保證以 \0 結尾)、data()(不保證)、copy()。
  • 子字串、追加、查找、刪除、取代、插入:substr()、append()、find()/rfind()、find_first_of() 等、erase()、replace()、insert()。
  • 行輸入:getline(cin, str) 安全讀取整行,避免緩衝區溢位。

異常處理機制

異常處理提供結構化錯誤處理流程,優於傳統錯誤碼或 errno。

基本語法

try {
    // 可能拋出異常的程式碼
    throw exception_object;
} catch (ExceptionType1& e) {
    // 處理 ExceptionType1
} catch (ExceptionType2& e) {
    // 處理 ExceptionType2
} catch (...) {
    // 捕獲所有其他異常
}

關鍵特性

  • 異常傳遞:拋出後離開正常流程,尋找最近的匹配 catch 區塊。若當前函式無匹配,向呼叫者傳遞,直到 main,若仍未處理則呼叫 terminate() 終止程式。
  • 重新拋出:在 catch 區塊中以 throw; 重新拋出當前異常。
  • 捕獲順序:衍生類別型別必須置於基底類別之前;catch(...) 必須置最後。
  • 異常規格:函式宣告可附加 throw(TypeList) 限制拋出型別。違反規格觸發 unexpected(),可由 set_unexpected() 設定處理函式。
  • 標準異常體系:以 std::exception 為基底,定義於 <exception>。自訂異常類別建議繼承 std::exception 並覆寫 what() 回傳錯誤描述。

輸入輸出串流(I/O Streams)

C++ I/O 架構以類別階層組織,核心類別包含:

  • ios:基底類別,管理格式旗標、錯誤狀態。
  • istream / ostream / iostream:輸入、輸出、雙向串流。
  • ifstream / ofstream / fstream:檔案串流。
  • istringstream / ostringstream / stringstream:字串串流,支援字串與數值互轉。
  • 預定義物件:cin、cout、cerr(不緩衝錯誤輸出)、clog(緩衝記錄輸出)。

格式化與非格式化操作

格式化輸入(>>)自動轉換字元為數值;非格式化輸入(get()、getline()、read())保持原始位元組。輸出同理。格式控制可用操縱子(hex、setw()、setprecision() 等)或成員函式(setf()、width()、fill()、precision())。

錯誤狀態與檔案定位

  • 狀態旗標:good()、eof()、fail()、bad()。串流物件可隱式轉為 bool 判斷狀態。
  • clear() 僅重設錯誤旗標,不清除緩衝區內容;需配合 ignore() 捨棄字元。
  • 檔案定位:seekg()/seekp() 移動讀/寫位置,支援相對開頭、目前位置、檔案末尾。
  • 二進制讀寫:read()/write() 直接搬移記憶體區塊。

字串與檔案串流範例

// 字串串流轉換
#include <sstream>
std::string s = "123 4.56";
std::istringstream iss(s);
int a; double b;
iss >> a >> b;

// 檔案串流
#include <fstream>
std::ofstream fout("data.txt", std::ios::out | std::ios::app);
fout << "Hello" << std::endl;
std::ifstream fin("data.txt");
std::string line;
while (std::getline(fin, line)) { /* ... */ }
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved