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

C++ 基礎進階完整教程:從語法增強到多態實現原理深度解析

     編輯:關於C++

課程概覽

本教程涵蓋 C++ 對 C 的核心擴展、類與對象、構造析構、運算符重載、繼承派生、多態機制、抽象類與面向接口編程、C 語言回調模擬多態等核心知識體系,適合從 C 轉 C++ 或夯實基礎的開發者系統學習。

一、C++ 對 C 的語法級增強

1. 命名空間 namespace

解決全局標識符衝突。std 封裝標準庫。三種用法:std::cout、using std::cout、using namespace std。支持嵌套與別名。

2. 實用性增強

  • 變量可就近聲明(C 強制開頭聲明)。
  • register 可取地址(編譯器自動優化,忽略請求)。
  • 禁止同名全局變量重複定義(C 允許 tentative definition)。
  • struct 直接成爲類型名,無需 typedef。
  • 所有函數必須顯式聲明返回類型與參數類型(C 隱式 int)。

3. bool 類型

關鍵字 true/false,佔 1 字節,非 0 自動轉 true。替代宏與整型標誌位。

4. 三目運算符返回左值

C++ 中 (a<b?a:b)=10 合法,因返回變量本身(實為常指針)。若含常量則不可作左值。

5. const 深度解析

聲明含義
const int* p指向常量的指針(數據不可改)
int* const p常指針(指針不可改)
const int* const p指向常量的常指針

C++ const vs C const:C++ const 編譯期進符號表,不佔存儲(除非取址/extern/全局),可作數組長度、模板參數;C const 為只讀變量,佔存儲。

二、引用專題

本質

引用是**已定義變量的別名**,底層實現為**常指針** T* const。聲明時必須初始化,之後不可重新綁定。

核心場景

  • 函數參數傳避拷貝:void f(int& x) 直接操作實參。
  • 返回值引用支持鏈式調用與左值賦值:int& f() { static int x; return x; } f() = 10;
  • 臨時對象綁定 const T& 延長生命周期:const int& r = 10; 編譯器生成臨時變量。
  • 指針引用 T*& 修改實參指針指向(如工廠函數分配內存)。

常見陷阱

  1. 返回棧上局部變量的引用 → 懸空引用,UB。
  2. 構造函數中調用構造函數(委託構造需 C++11)。
  3. const 引用綁定字面值時編譯器隱式創建臨時對象。

三、類與對象核心機制

封裝與訪問控制

public/protected/private 控制成員可見性。struct 默認 public,class 默認 private。友元 friend 打破封裝(函數/類)。

構造/析構/拷貝控制

  • 構造函數同名、無返回類型、可重載。初始化列表**必須**用於:const 成員、引用成員、無默認構造的成員對象、基類構造。
  • 析構函數 ~Class(),逆序調用(成員→基類)。
  • 淺拷貝問題:指針成員需深拷貝,實現拷貝構造與 operator=(檢查自賦值、釋放舊資源、分配新資源、拷貝數據、返回 *this)。
  • 對象數組/動態創建:new T[n] 調用默認構造,delete[] 逆序析構。

靜態成員

static 成員屬於類,不屬於對象。聲明在類內,定義在類外 int Class::member = 0;。靜態函數無 this,只能訪問靜態成員。

對象模型與 this 指針

  • 非靜態數據成員存儲於對象內存布局(同 struct,含對齊)。
  • 非靜態成員函數隱式第一參數 Class* const this。
  • 靜態成員函數無 this,類似全局函數但受訪問控制。
  • sizeof(Class) 不包含靜態成員與函數代碼。

四、運算符重載

兩種形式

  • 成員函數:Complex operator+(const Complex& rhs),左操作數為 *this。
  • 全局函數(常配合 friend):Complex operator+(const Complex&, const Complex&),雙操作數顯式,支持隱式轉換(如 `cout << obj`)。

必須為成員函數的運算符

= [] () ->(涉及對象內部狀態/調用語義)。

重點運算符實現模式

運算符返回類型關鍵點
+ - * /值返回臨時對象,不可為引用
+= -=T&修改 *this,返回引用支持鏈式
++ -- 前置T&修改後返回 *this
++ -- 後置值參數 int 佔位,保存舊值返回
[]T&/const T&支持讀寫,常做雙重載
()任意仿函數調用語法
<< >>ostream&/istream&全局 friend,返回流引用支持鏈式
=T&深拷貝,檢查自賦值,釋放舊資源
-> *指針/引用智能指針核心,模擬原生指針行為

不建議重載

&& || ,(逗號運算符):重載後失去短路求值/順序點語義,參數會預先求值。

五、繼承與派生

繼承方式影響訪問屬性

基類成員public 繼承protected 繼承private 繼承
publicpublicprotectedprivate
protectedprotectedprotectedprivate
private不可訪問不可訪問不可訪問

「三看原則」:看調用位置(類內/外)、看繼承方式、看基類成員屬性。

構造/析構順序

  1. 基類構造(按繼承聲明順序)→ 成員對象構造(按聲明順序)→ 派生類構造。
  2. 析構順序完全相反。
  3. 基類帶參構造必須在派生類初始化列表顯式調用。

多重繼承與虛繼承

菱形繼承導致基類子對象重複,數據冗余與二義性。virtual 繼承確保僅一份基類子對象,通過虛基類表指針間接訪問。構造時**最派生類**直接調用虛基類構造,中間類不再調用。

六、多態:核心機制與工程意義

成立三條件

  1. 公有繼承(is-a 關係)。
  2. 基類聲明 virtual 函數,派生類**同原型**重寫(override)。
  3. 基類指針/引用指向派生類對象,通過指針/引用調用虛函數。

底層實現:虛函數表

  • 含虛函數的類,編譯器生成**虛函數表**,存儲虛函數地址。
  • 每個對象隱式包含 **vptr** 指向其類的虛表(通常位於對象首地址)。
  • 調用 ptr->vfunc() → ptr->vptr[vfunc_index](),運行期動態綁定。
  • sizeof 含虛函數類 = 數據成員 + vptr(通常 4/8 字節)。

關鍵面試考點

  1. 構造/析構中調用虛函數:構造時 vptr 逐層設置,調用**當前構造類**的版本,不會多態到派生類;析構同理。
  2. 虛析構必要性:delete base_ptr 釋放派生對象時,若基類析構非虛,僅調用基類析構 → 派生資源洩漏。
  3. 純虛函數 =0:強制派生類實現,構成抽象類,不可實例化。可提供定義供派生類調用。
  4. override/final (C++11):編譯期檢查重寫正確性、禁止進一步重寫/繼承。

七、抽象類與面向接口編程

純虛函數定義接口

class ISocketProtocol {
public:
    virtual bool connect(const char* ip, int port) = 0;
    virtual int send(const void* buf, int len) = 0;
    virtual int recv(void* buf, int len) = 0;
    virtual ~ISocketProtocol() {} // 虛析構
};

多實現類繼承接口,框架層依賴抽象,具體廠商實現注入(依賴倒置/控制反轉 IOC)。

多接口繼承替代多重實現繼承

C++ 無 `interface` 關鍵字,慣用**純抽象類**模擬。類可繼承多個接口(無數據成員、無實現),避免菱形與二義性,實現「接口隔離」。

八、C 語言模擬多態:回調函數與函數指針

函數指針語法

typedef int (*EncFunc)(unsigned char* in, int inLen,
                       unsigned char* out, int* outLen, void* ctx, int ctxLen);

回調模式

  1. 框架定義函數指針類型(協議)。
  2. 廠商實現具體函數,簽名匹配。
  3. 框架保存/傳遞函數指針,事件發生時間接調用。
  4. 實現「調用者與實現者解耦」,類似 C++ 虛函數表機制(手動維护函數指針表)。

動態庫升級框架案例

Socket 庫定義 EncFunc/DecFunc 類型,預留註冊入口 register_encrypt(EncFunc)。多廠商加密庫實現協議,運行期動態加載並註冊,核心庫零修改集成新算法。

九、學習路線圖與避坑指南

  1. 語法基礎:引用、const、命名空間、函數重載/默認參數/內聯。
  2. 類機制:構造/析構/拷貝/移動、初始化列表、靜態成員、友元、運算符重載。
  3. 繼承多態:訪問控制、構造順序、虛函數表、虛繼承、抽象類、接口設計。
  4. STL 實戰:容器選型、算法組合、迭代器失效、智能指針、RAII、異常安全。
  5. 工程思維:面向接口、依賴倒置、設計模式(策略/工廠/觀察者)、代碼審查清單。

常見誤區:

  • 以為引用不佔內存(實為常指針,佔指針大小)。
  • 所有函數聲明 virtual(構造不能虛、內聯虛函數無意義、性能開銷)。
  • 忽略拷貝控制導致雙重釋放/淺拷貝 Bug。
  • 多重繼承濫用(優先組合+接口)。
  • C 風格指針混用 C++ 智能指針(所有權語義混亂)。

十、參考資源

  • 《The C++ Standard Library》Nicolai M. Josuttis
  • 《Effective C++》/《Effective Modern C++》Scott Meyers
  • 《C++ Primer》Stanley B. Lippman
  • ISO C++ 標準草案:eel.is/c++draft
  • 在線參考:cppreference.com
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved