繼承是 C++ 實現程式碼重用的核心機制之一。當定義新類別時,若想重用既有類別的功能,即可透過繼承實現。語法形式為 class NewClass : public OldClass { /* 新增成員 */ };。子類別將繼承父類別的所有成員(包含私有、保護、公開),但私有成員在子類別中無法直接存取。繼承方式分為 public、private、protected 三種,實務上以 public 最為常見,因能保持成員原有的存取層級。
BaseClass::func() 明確指定。virtual 關鍵字,可確保最終衍生類別僅保留一份虛擬基底類別的成員。虛擬基底類別的建構子由最底層的衍生類別直接初始化。多態指「一個介面,多種實現」。透過基底類別指標或參考指向衍生類別物件,呼叫虛擬函式時,系統依物件實際類型決定呼叫哪個版本,實現執行期綁定。
以 virtual 宣告的函式為虛擬函式。編譯器為每個含虛擬函式的類別建立虛擬函式表(vtable),儲存虛擬函式位址。每個物件內含一指標(vptr)指向其類別的 vtable,使物件大小增加 4 位元組(32 位元系統)。衍生類別覆寫虛擬函式時,函式名稱、參數表、回傳型別必須一致(回傳型別允許共變)。
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_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() 回傳錯誤描述。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)) { /* ... */ }