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

C++ 全面總結(含 C++11):從 OOP 核心到 STL 算法的系統性梳理

     編輯:C++ 入門

第一部分:OOP 核心 —— 類與對象

1. this 指針:隱含的「自我」

每個非靜態成員函數隱含一個參數 Type* const this,指向調用對象。const 成員函數則為 const Type* const this。

struct A { int a; void set(int a) { this->a = a; } };

用途:解決參數遮蔽成員、返回 *this 實現鏈式調用。

2. const 成員函數:承諾不修改對象

  • 只能調用 const 成員函數,只能返回 const 引用/指針。
  • 非 const 對象優先調用非 const 重載;const 對象只能調用 const 版本。
  • 構造函數不能是 const——否則無法初始化。

3. 函數重載的本質:符號表修飾

C 編譯器符號表只記錄函數名 → 無重載。C++ 符號包含:類名 + 函數名 + 參數列表 + const屬性 → 支持重載。返回類型不參與修飾,故不可按返回值重載。

4. 構造函數初始化列表:真正的初始化

Person(int id, string name, int age) : _id(id), _name(name), _age(age) { }
  • 初始化列表執行初始化(調用拷貝/移動構造);函數體內賦值是賦值(先默認構造再 operator=)。
  • 必須用初始化列表的情況:const 內置類型、引用成員、無默認構造的類類型成員。

5. 成員初始化順序 = 聲明順序

class X { int i; int j; X(int v): j(v), i(j) {} }; // 錯!i 先初始化,讀取未初始化的 j

無論列表寫順序如何,編譯器按類內聲明順序初始化。

6. 析構函數:歸還資源的最後一站

  • 棧對象:離開作用域自動調用析構 → 系統回收棧內存。
  • 堆對象:delete p = p->~T() + operator delete(p)。析構函數不負責釋放對象自身內存,只負責清理成員持有的資源。

7. static 成員:屬於類,不屬於對象

  • 數據成員:單一實例,類外定義初始化。
  • 成員函數:無 this 指針,只能訪問 static 成員,不能是 const(因為不屬於對象)。
  • 類外定義不寫 static 關鍵字。

8. 友元:單向的「特權」

  • 類/函數可被聲明為友元,訪問 private/protected。
  • 友元關係不傳遞、不繼承、單向(A 是 B 友元 ≠ B 是 A 友元)。

第二部分:STL 順序容器

1. 五種初始化方式

  1. vector<T> v; 空容器
  2. vector<T> v2(v1); 拷貝構造(要求類型完全相同)
  3. vector<T> v(n); 指定大小,值初始化
  4. vector<T> v(n, val); 指定大小與值
  5. vector<T> v(beg, end); 迭代器範圍(容器類型可不同,元素類型可隱式轉換)

2. 元素類型約束

須支持拷貝構造與賦值。private 拷貝構造/賦值運算符的類無法放入 vector。

3. 迭代器四大金剛

  • begin() / end():正向遍歷
  • rbegin() / rend():逆向遍歷(邏輯上指向前一元素)

4. 插入操作

  • push_back / push_front(list 專有)
  • insert(pos, val)、insert(pos, n, val)、insert(pos, beg, end)

5. 刪除操作與迭代器失效

// 正確刪除偶數
auto it = v.begin();
while (it != v.end()) {
    if (*it % 2 == 0) it = v.erase(it);  // erase 返回下一有效迭代器
    else ++it;
}

失效規則:

  • vector:插入/刪除導致重新分配或元素移動 → 所有迭代器失效。
  • list:僅指向被刪元素的迭代器失效,其餘不變。

6. vector 容量管理

  • size():元素數
  • capacity():已分配空間可容納數
  • reserve(n):預分配,避免擴容拷貝
  • resize(n):改變元素數(擴展時值初始化)

7. for_each 與 Lambda

for_each(v.begin(), v.end(), [](const string& s){ cout << s << ' '; });

C++11 Lambda 讓單次回調無需命名函數,極大簡化代碼。

8. string::substr 截取子串

string s = "helloworld";
string sub = s.substr(1, 4); // "ello"  從下標 1 取 4 個字符

迭代器範圍是 [beg, end),下標操作是 pos + len。

9. 容器適配器

  • stack:LIFO,push/top/pop
  • queue:FIFO,push/front/pop
  • priority_queue:堆實現,默認 less(大根堆),可傳 greater 或自定義比較器

10. 反向迭代器的物理/邏輯差異

rbegin() 物理指向 end(),邏輯指向最後一元素。erase 不接受反向迭代器,需轉換:it = reverse_iterator(s.erase((++it).base()))。

第三部分:STL 關聯容器

1. pair:鍵值對,非容器

構造:p = {k,v}、make_pair(k,v)、p.first=k; p.second=v;。

2. map:紅黑樹實現的有序鍵值映射

  • m[key] = val:若 key 不存在會插入默認值(副作用)。
  • insert({k,v}):返回 pair<iterator,bool>,失敗不修改原值。
  • find(k) / count(k):安全查找,不插入。
  • Key 必須支持 operator<(或自定義 Compare)。
  • 查找 O(log n)。

3. set:有序唯一元素集合

  • 紅黑樹,按值排序,自動去重。
  • 用法同 map,無 key/value 之分。

4. unordered_map/set (C++11):哈希表,無序,平均 O(1)

  • 需 Key 支持 hash 與 ==。
  • 需有序遍歷用 map/set;純查找用 unordered_* 更快。

第四部分:STL 算法精選

  • for_each:遍歷執行函數
  • count / count_if:計數
  • min_element / max_element:最值迭代器(可傳比較器)
  • find / find_if:查找首個滿足條件元素
  • copy:配合 back_inserter/front_inserter 跨容器複製
  • Lambda:[捕獲](參數){體},C++11 起支持,解決「臨時函數命名難」問題

第五部分:復制控制(三法則/五法則)

1. 拷貝構造函數

T(const T& other) : member(other.member) { }

調用時機:對象初始化、傳值參數、返回值(非 NRVO)。

2. 深拷貝 vs 淺拷貝

  • 淺拷貝:編譯器默認,逐位拷貝指針值 → 多對象共享同一資源 → 雙重釋放崩潰。
  • 深拷貝:自定義拷貝構造,分配新資源拷貝內容 → 各自擁有獨立資源。

3. 賦值運算符

T& operator=(const T& rhs) {
    if (this == &rhs) return *this;  // 自賦值檢查
    delete [] ptr;                   // 釋放舊資源
    ptr = new char[strlen(rhs.ptr)+1];
    strcpy(ptr, rhs.ptr);
    return *this;
}

核心:先釋放舊資源,再獲取新資源,處理自賦值。

4. 禁止拷貝/賦值

class NonCopyable {
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable& operator=(const NonCopyable&) = delete;
};

或用宏 DISALLOW_COPY_AND_ASSIGN(Type)(Google 風格)。繼承 NonCopyable 也可。

5. 三法則/五法則

  • C++98:析構、拷貝構造、賦值運算符 —— 三者一起出現或一起缺席。
  • C++11:+ 移動構造、移動賦值 —— 五法則。

6. 值語義 vs 對象語義

  • 值語義:拷貝後邏輯獨立(如 int, string, vector)。
  • 對象/引用語義:拷貝僅複製句柄,共享底層資源(如 shared_ptr, 文件句柄封裝)。

(本文持續更新中,涵蓋模板、智能指針、並發、C++17/20 新特性...)

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved