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

C++ 核心筆記 (二):建構函式與解構函式完整解析

     編輯:關於C++

1. 建構函式

建構函式是類別的特殊成員函式,名稱與類別相同,無傳回型別 (連 void 都不能寫)。當建立類別物件時,編譯器自動呼叫對應的建構函式完成初始化。

定義語法


class MyClass {
public:
    MyClass();                    // 預設建構函式 (無參數)
    MyClass(int a, double b);     // 多參數建構函式
    MyClass(const MyClass& other); // 複製建構函式
    // ...
};
// 類別外定義
MyClass::MyClass(int a, double b) : m_a(a), m_b(b) { /* 函式本體 */ }

特性

  • 可多載:參數個數、型別、順序不同即可共存。
  • 不可為 virtual、static、const、volatile。
  • 程式碼不可直接呼叫 (如 obj.MyClass() 錯誤),僅隱含於物件建立、陣列建立、new 運算、暫時物件建立、複製初始化等場合。
  • 主要任務:初始化資料成員、配置資源 (記憶體、檔案控制代碼、鎖等)。

2. 建構函式多載與預設參數


class Point {
    int x, y;
public:
    Point() : x(0), y(0) {}               // 1. 無參數 (預設建構)
    Point(int x_, int y_) : x(x_), y(y_) {} // 2. 兩參數
    Point(int val) : x(val), y(val) {}      // 3. 單參數 (隱含轉換來源)
    Point(int x_ = 0, int y_ = 0) : x(x_), y(y_) {} // 4. 預設參數 (取代 1+3)
};

注意:若類別自行定義任何建構函式,編譯器不再自動產生預設建構函式。若仍需無參數建構,必須額外提供 (或使用預設參數)。

3. 複製建構函式

形式:ClassName(const ClassName& other) (參數慣例為 const 左值參考)。

  • 用途:以現有物件初始化新物件 (如 MyClass b = a;、傳值參數、傳值回傳)。
  • 若未自訂,編譯器產生預設複製建構:逐位元複製所有非靜態資料成員 (淺層複製)。
  • 必須自訂 的情況:類別擁有指標成員、資源控制代碼、動態記憶體 等需深層複製或引用計數的資源。

範例:深層複製


class String {
    char* data;
    size_t len;
public:
    String(const char* s = "") {
        len = strlen(s);
        data = new char[len + 1];
        strcpy(data, s);
    }
    // 複製建構函式:深層複製
    String(const String& other) : len(other.len) {
        data = new char[len + 1];
        strcpy(data, other.data);
    }
    ~String() { delete[] data; }
    // ... 指派運算子、移動語意等 ...
};

4. 解構函式

名稱:~ClassName()。無參數、無傳回型別、不可多載 (一個類別只能有一個)。

  • 物件生命結束時自動呼叫:區域物件離開作用域、delete 動態物件、程式結束銷毀全域/靜態物件。
  • 主要任務:釋放資源 (記憶體、檔案、鎖、Socket、資料庫連線等)。
  • 若未自訂,編譯器產生空的預設解構函式。
  • 基底類別解構函式應宣告為 virtual,確保透過基底指標 delete 衍生物件時正確呼叫衍生解構函式。

解構順序

  1. 衍生類別解構函式本體執行。
  2. 成員物件解構函式 (依宣告順序反向)。
  3. 基底類別解構函式 (依繼承順序反向)。

即:建構順序與解構順序完全相反。

5. 成員物件初始化 (初始化清單)

當類別包含類別型別成員 (成員物件) 時,建構函式必須透過初始化清單 呼叫其建構函式,賦值方式 (member = value;) 會先呼叫預設建構再指派,效率低且無法處理 const/參考成員。


class Engine { public: Engine(int hp); };
class Car {
    Engine engine;      // 成員物件
    const int vin;      // const 成員
    int& refCounter;    // 參考成員
public:
    Car(int hp, int vin_, int& ref) : engine(hp), vin(vin_), refCounter(ref) {
        // 函式本體:engine 已建構完成,vin/refCounter 已初始化
    }
};

6. const 物件與 const 成員函式

const 物件


const MyClass obj(args); // 必須初始化,不可修改
obj.NonConstMethod();    // 錯誤:無法透過 const 物件呼叫非 const 成員函式
obj.ConstMethod();       // 正確

const 成員函式


class MyClass {
    int value;
public:
    void SetValue(int v) { value = v; }          // 非 const
    int GetValue() const { return value; }       // const:承諾不修改資料成員
    // int GetValue() { return value; }           // 可與上方構成多載 (const 屬於函式型別一部分)
};
  • const 關鍵字置於參數列後、函式本體前,屬於函式簽章一部分,定義與實作皆須保留。
  • const 成員函式可讀取資料成員,不可修改 (除非該成員宣告為 mutable),也不可呼叫非 const 成員函式。
  • const 物件只能呼叫 const 成員函式。

7. const/參考資料成員的初始化

只能 在初始化清單中初始化,不可在函式本體賦值:


class Demo {
    const int MAX_SIZE;
    int& ref;
public:
    Demo(int max, int& r) : MAX_SIZE(max), ref(r) {} // 正確
    // Demo(int max, int& r) { MAX_SIZE = max; ref = r; } // 錯誤:編譯失敗
};

8. 類別作用域與作用域解析運算子 ::

  • 類別定義內部即為類別作用域。
  • 類別外定義成員函式時,必須 使用 ClassName::MemberName 指明隸屬。
  • 成員函式內若區域變數與資料成員同名,需用 ClassName::member 或 this->member 區分。
  • 類別外存取 public 成員:obj.member 或 ptr->member。

9. 完整範例程式


#include <iostream>
#include <cstring>
using namespace std;

class TestConst {
    int m;
public:
    TestConst(int v = 0) : m(v) { cout << "建構: " << m << endl; }
    ~TestConst() { cout << "解構: " << m << endl; }

    void SetValue(int v) { m = v; }
    void Show() { cout << "m = " << m << endl; }
    void Show() const { cout << "const m = " << m << endl; } // 多載
};

int main() {
    TestConst c1(100);         // 一般物件
    const TestConst c2(200);   // const 物件

    c1.SetValue(300);
    c1.Show();  // 呼叫 void Show()
    c2.Show();  // 呼叫 void Show() const
    // c2.SetValue(400);      // 編譯錯誤:const 物件不可呼叫非 const 函式
    return 0;
}

重點總結

概念關鍵規則
建構函式同名、無傳回型別、可多載、自動呼叫、初始化清單優於賦值
複製建構const 參考參數、深層複製資源、預設為淺層複製
解構函式~ClassName()、無參數、不可多載、virtual 基底、逆序執行
const 物件只能呼叫 const 成員函式、需初始化
const 成員函式承諾不修改成員、可多載、定義實作皆需 const
const/參考成員只能在初始化清單初始化
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved