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

C++ 類機制全解析:封裝、繼承、多態與成員函數深度解析

     編輯:關於C++

前言

類是 C++ 面向對象程序設計的核心構建塊,實現了數據與操作的封裝、繼承復用與多態擴展。本文系統講解類的定義結構、訪問控制、成員函數特性、this 指針機制、構造/析構/拷貝語義、靜態成員、友元等核心概念,配合代碼示例與內存模型圖解。

一、類的定義與基本結構


class Clock {
public:      // 公有接口:外部可訪問
    void setTime(int h, int m, int s);
    void showTime() const; // 常成員函數

protected:   // 保護成員:派生類可訪問
    int timezone_;

private:     // 私有成員:僅本類內部可訪問
    int hour_, minute_, second_;
    bool isValid(int h, int m, int s) const; // 內部輔助函數
};

關鍵點

  • class 默認成員為 private;struct 默認 public。
  • 封裝目的:隱藏實現細節、保護數據不變量、提供穩定接口。
  • 成員分類:數據成員(屬性)+ 成員函數(行為)。

二、訪問控制詳解

訪問位置publicprotectedprivate
類內部✓✓✓
派生類內部✓✓✗
類外部 (對象/指針/引用)✓✗✗

最佳實踐:數據成員盡量 private,提供 public/protected 存取器;實現細節函數 private;派生類需訪問的內部接口 protected。

三、成員函數深度解析

1. 定義方式


// 類內定義(隱式 inline)
class A { void foo() { /* ... */ } };

// 類外定義(需作用域限定)
void A::foo() { /* ... */ }
  • 類內定義適用於簡短函數(1-5 行),編譯器可能內聯優化。
  • 類外定義分離接口與實現,利於編譯防火牆、減少頭文件依賴。

2. this 指針機制

  • 每個非靜態成員函數隱含參數 ClassName* const this。
  • 調用 obj.func() 實際轉為 ClassName::func(&obj)。
  • 成員訪問 member 隱式轉為 this->member。
  • const 成員函數:void foo() const ⇒ this 類型為 const ClassName* const,不可修改非 mutable 成員。

3. 重載、覆寫、隱藏

概念範圍條件關鍵字
重載同一作用域參數列表不同無
覆寫基類/派生類同名、同參數、基類虛函數override (C++11)
隱藏基類/派生類同名、參數不同 或 基類非虛無

4. 靜態成員函數

  • 無 this 指針,僅能訪問靜態成員。
  • 調用方式:ClassName::staticFunc() 或 obj.staticFunc()。
  • 本質是類作用域的全局函數,不參與多態。

四、對象生命週期管理

1. 構造函數

  • 名稱與類同,無返回類型。
  • 初始化列表:Clock(int h, int m, int s) : hour_(h), minute_(m), second_(s) {} —— **優先於函數體執行**,對 const、引用、無默認構造的成員**必須**在列表初始化。
  • 委託構造 (C++11):Clock() : Clock(0,0,0) {}。
  • explicit 防止隱式轉換:explicit Clock(int h);。

2. 析構函數

  • ~ClassName(),無參數、無返回值、不可重載。
  • **基類析構函數必須聲明為 virtual**,否則通過基類指針刪除派生對象時僅調用基類析構,導致資源洩漏。
  • 自動釋放成員對象資源(成員析構順序與構造相反)。

3. 拷貝/移動語義 (C++11)

操作函數簽名默認行為何時自定義
拷貝構造Class(const Class&)逐成員拷貝管理動態資源/句柄
拷貝賦值Class& operator=(const Class&)逐成員賦值同上
移動構造Class(Class&&) noexcept逐成員移動資源盜取優化
移動賦值Class& operator=(Class&&) noexcept逐成員移動賦值同上

Rule of Five:若自定義了上述任一,通常需全部顯式聲明(或 =default/=delete)。

五、特殊成員與進階特性

1. 友元

  • friend class B; / friend void func(Class&);
  • 打破封裝,慎用。常用於:運算符重載需訪問私有數據、特定工具類協作。

2. 巢狀類


class Outer {
    class Inner { /* ... */ }; // 內部類
    Inner in_; // 可直接使用
};
// 外部使用:Outer::Inner obj;

內部類是外部類的成員,**不自動擁有外部類對象訪問權**(需傳遞外部對象引用)。

3. 匿名對象


Clock(10, 30, 0).showTime(); // 臨時對象,表達式結束即析構

六、內存佈局模型

+------------------+
| 非靜態數據成員   |  ← 按聲明順序排列(中間可能有填充對齊)
+------------------+
| 虛函數表指針(vptr)|  ← 有虛函數時,通常放對象首地址
+------------------+
| 基類子對象       |  ← 多繼承時多個基類子對象
+------------------+
  • 靜態數據成員**不在對象內**,存儲在全局/靜態存儲區。
  • 虛繼承引入 vbptr (虛基類表指針),佈局更複雜。
  • sizeof(Class) 包含所有非靜態數據 + 填充 + vptr/vbptr,不包含靜態成員。

七、最佳實踐清單

  1. 數據成員 private,行為 public。
  2. 構造函數用初始化列表,explicit 防隱式轉換。
  3. 基類析構 virtual,覆寫加 override。
  4. 管理資源遵循 RAII,優先用智能指針/容器避免手動 new/delete。
  5. 拷貝/移動語義顯式控制(=default/=delete/自定義)。
  6. const 正確性:只讀函數加 const,參數傳 const T&。
  7. 慎用友元、多重繼承、虛繼承,優先組合/接口繼承。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved