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

C++ 構造函數與析構函數詳解:資源獲取即初始化 (RAII) 核心模式

     編輯:關於VC++

構造函數

  • 名稱與類別相同,無返回類型
  • 可多載 (參數不同)
  • 物件建立時自動調用
  • 用途:初始化成員、分配資源 (記憶體、檔案控制代碼、Socket、鎖...)

析構函數

  • 名稱 ~ClassName(),無參數、無返回值、不可多載 (一個類別僅一個)
  • 物件銷毀時自動調用:
    • 區域物件離開作用域
    • delete 動態物件
    • 程式結束時全域/靜態物件
  • 用途:釋放構造函數獲取的所有資源

RAII 經典範例


class Student {
    char* m_pName; // 動態記憶體
public:
    Student() { m_pName = new char[20]; }           // 獲取資源
    ~Student() { delete[] m_pName; }                // 釋放資源

    // C++11 起建議刪除拷貝/移動或實現深拷貝
    Student(const Student&) = delete;
    Student& operator=(const Student&) = delete;
};

若無析構函數釋放 m_pName,每建立一個 Student 物件就洩漏 20 bytes → 記憶體洩漏。

成員初始化清單 (推薦寫法)


class Point {
    int x, y;
    const int id;       // const 成員必須在清單初始化
    std::string name;   // 類別型別成員建議清單初始化 (避免預設建構+賦值)
public:
    Point(int x_, int y_, int id_, std::string n_)
        : x(x_), y(y_), id(id_), name(std::move(n_)) {} // 高效、正確
};

常見錯誤

錯誤代碼問題修正
class A { int x = 0; };C++98/03 類別內不可直接賦值 (C++11 允許非靜態成員預設值)移至構造函數初始化清單
~A(int x) {}析構函數不可帶參數移除參數
class B { ~B(); ~B(int); };析構函數不可多載保留單一無參數版本
動態陣列 delete p (非 delete[])未正確釋放陣列,行為未定義嚴格配對 new[]/delete[]

進階:資源管理封裝 (智慧指標/容器)

現代 C++ (C++11+) 建議直接使用標準庫封裝,而非手寫 new/delete:

  • std::unique_ptr:獨佔所有權,離開作用域自動 delete
  • std::shared_ptr:共享所有權,引用計數歸零自動 delete
  • std::vector/std::string:動態陣列/字串自動管理記憶體
  • std::lock_guard:鎖定作用域自動解鎖

// 現代寫法:零手動資源管理
class Student {
    std::string m_name; // 自動管理字串記憶體
    std::vector m_scores;
public:
    Student(std::string n) : m_name(std::move(n)) {}
    // 無需析構函數!編譯器自動合成正確析構
};

總結

  1. 構造函數獲取資源,析構函數釋放資源 — 這是 RAII 核心
  2. 析構函數唯一、無參、無返回,保證在物件生命週期結束時確定性調用
  3. 善用成員初始化清單,避免預設建構+賦值的雙重開銷
  4. 現代 C++ 應優先使用標準庫智慧指標/容器,讓編譯器自動生成正確析構邏輯
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved