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

C++ 進階核心總結:模板、類型轉換、異常、I/O 流與 STL 完整指南

     編輯:關於C++

第 6 章:函數模板與類模板

6.1 函數模板

語法:

template <typename T>
void swap(T& a, T& b) {
    T tmp = a; a = b; b = tmp;
}

調用方式:

  • 隱式推導:swap(a, b) —— 編譯器根據實參類型推導 T
  • 顯式指定:swap<int>(a, b) —— 強制類型

模板 vs 重載 vs 普通函數

特性函數模板普通函數
隱式類型轉換不允許允許
優先級較低優先匹配
完全匹配時優於普通函數—

可用 swap<>(a,b) 強制使用模板。

編譯器雙重編譯機制

  1. 聲明處:編譯模板代碼本身(語法檢查)
  2. 調用處:根據具體類型實例化,編譯生成的具體函數

反彙編可見:__Z6myswapIiEvRT_S1_ (int版)、__Z6myswapIcEvRT_S1_ (char版) —— 編譯器生成了兩個獨立函數。

6.2 類模板

語法:

template <typename T>
class Array {
    T* data;
    int size;
public:
    Array(int n) : size(n), data(new T[n]) {}
    T& operator[](int i) { return data[i]; }
    ~Array() { delete[] data; }
};

關鍵規則

  • 繼承類模板時,子類必須指定父類模板參數:class B : public A<int>
  • 成員函數類外定義需帶模板前綴:template<typename T> void A<T>::func()
  • 友元函數處理複雜,建議僅用於運算符重載
  • 靜態成員:每個實例化類型擁有獨立副本

容器值語義

STL 容器存儲的是值副本,而非引用。存入的類型必須提供:

  1. 拷貝構造函數
  2. 拷貝賦值運算符
  3. 析構函數(如有動態資源)

若類含裸指針,必須實現深拷貝(三大件/五大件)。

第 7 章:C++ 類型轉換

運算符用途示例
static_cast基本類型轉換、有繼承關係的指針/引用轉換(編譯期檢查)int i = static_cast<int>(3.14)
reinterpret_cast無關類型指針轉換、整數與指針互轉(危險,僅重新解釋位模式)int* p = reinterpret_cast<int*>(charPtr)
dynamic_cast多態類型轉換(運行期檢查,需虛函數),失敗返回 nullptrDerived* d = dynamic_cast<Derived*>(basePtr)
const_cast移除 const/volatile 屬性char* p = const_cast<char*>(str.c_str())

原則

  • 盡量避免強制轉換
  • 優先使用 static_cast,明確意圖且有檢查
  • reinterpret_cast 極少用,僅用於極底層代碼
  • dynamic_cast 僅用於多態層級轉換

第 8 章:異常處理

基本語法

try {
    // 可能拋出異常的代碼
    if (error) throw MyException("msg");
} catch (const MyException& e) {
    // 處理特定異常
} catch (...) {
    // 捕獲所有其他異常
}

核心機制

  • 棧解旋:異常拋出後,沿調用棧向上尋找匹配的 catch,途經的所有局部對象自動析構(逆序)
  • 類型匹配:嚴格類型匹配,不允許隱式轉換(throw 'c' 不能被 catch(int) 捕獲)
  • 異常對象生命週期:拋出時拷貝構造到異常處理機制管理的內存,catch 參數再次拷貝/引用

異常接口聲明

void func() throw(MyException, std::bad_alloc);  // 只能拋出列出類型及其子類
void func() throw();  // 不拋出任何異常
// 無聲明 = 可拋出任意異常

違反聲明會調用 unexpected(),默認調用 terminate() 終止程序。

標準異常體系

  • std::exception 基類,what() 返回錯誤信息
  • std::bad_alloc:new 失敗
  • std::out_of_range:越界訪問
  • std::invalid_argument:無效參數

第 9 章:C++ I/O 流

流體系結構

ios (基類)
├── istream (輸入) ← cin
├── ostream (輸出) ← cout, cerr, clog
└── iostream (輸入輸出)
    ├── ifstream (文件輸入)
    ├── ofstream (文件輸出)
    └── fstream (文件輸入輸出)

標準流對象

對象類設備C 對應
cinistream_withassign鍵盤stdin
coutostream_withassign屏幕stdout
cerrostream_withassign屏幕(無緩衝)stderr
clogostream_withassign屏幕(有緩衝)stderr

格式化輸出控制

兩種等價方式:

// 1. 成員函數
cout.setf(ios::hex); cout.setf(ios::showbase);
cout.width(10); cout.fill('*');

// 2. 操縱符 (需 #include )
cout << hex << showbase << setw(10) << setfill('*');

常用操縱符:dec/hex/oct、fixed/scientific、setprecision(n)、setw(n)、left/right/internal、showpos/showpoint。

文件流關鍵點

  • 打開模式:ios::in/out/app/ate/trunc/binary 可組合(|)
  • 文本 vs 二進制:文本模式換行符轉換,二進制模式原樣讀寫
  • 二進制讀寫:read(char*, size) / write(const char*, size),配合 reinterpret_cast 存取結構體
  • 隨機訪問:seekg/seekp (輸入/輸出指針),tellg/tellp

第 10 章:STL 核心技術

六大組件

  1. 容器:vector, list, deque, set, map, stack, queue, priority_queue...
  2. 算法:sort, find, copy, transform, accumulate...
  3. 迭代器:連接容器與算法的膠水
  4. 仿函數:重載 operator() 的類,作為算法策略
  5. 適配器:stack/queue/priority_queue 適配 deque;reverse_iterator 適配器
  6. 空間配置器:allocator 管理內存分配

容器選型指南

迭代器分類與能力

輸入迭代器  →  輸出迭代器  →  前向迭代器  →  雙向迭代器  →  隨機訪問迭代器
  (只讀)       (只寫)         (可多遍歷)      (可雙向)        (可算術/比較)
                    ↑
            list/set/map 支持到這裡
vector/deque 支持到隨機訪問

常用算法分類速查

  • 非可變序列:find, count, equal, search, mismatch, lexicographical_compare
  • 可變序列:copy, transform, replace, remove, fill, generate, swap
  • 排序相關:sort, stable_sort, partial_sort, nth_element, merge, inplace_merge
  • 堆操作:make_heap, push_heap, pop_heap, sort_heap
  • 集合運算:set_union, set_intersection, set_difference (要求有序)
  • 排列組合:next_permutation, prev_permutation
  • 數值計算:accumulate, inner_product, partial_sum, adjacent_difference

仿函數與適配器

// 預定義仿函數
plus(), minus(), multiplies(), divides(), modulus(), negate()
equal_to(), not_equal_to(), greater(), less(), greater_equal(), less_equal()
logical_and(), logical_or(), logical_not()

// 適配器:bind1st/bind2nd (C++11 建議用 std::bind/lambda)
// 否定器:not1 (一元), not2 (二元)

sort(v.begin(), v.end(), greater());  // 降序
count_if(v.begin(), v.end(), bind2nd(greater(), 5));  // 計算 >5 的個數

STL 設計精髓

  1. 容器-算法分離:迭代器作為中介,算法不依賴具體容器
  2. 值語義:容器存副本,元素需可拷貝
  3. 類型參數化:模板實現泛型,編譯期實例化,零運行期開銷
  4. 高效實現:紅黑樹、動態數組、堆等經典數據結構的工業級實現

學習建議

  • 熟練掌握 vector, map, set, sort, find, lower_bound 等高頻組件
  • 理解迭代器失效規則(vector 插入刪除可能失效所有迭代器)
  • 善用 auto、範圍 for、lambda (C++11+) 簡化代碼
  • 閱讀 <algorithm> 實現,學習泛型編程技巧
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
場景推薦容器理由
隨機訪問、尾部增刪vector連續內存、緩存友好
頭尾雙向增刪deque分段連續、頭尾 O(1)
中間頻繁增刪list雙向鏈表、迭代器穩定
鍵值查找、自動排序map紅黑樹、O(log n)
唯一鍵集合、排序set紅黑樹、去重
後進先出stackdeque 適配
先進先出queuedeque 適配
優先級隊列priority_queue堆實現