建構函式是類別的特殊成員函式,名稱與類別相同,無傳回型別 (連 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 運算、暫時物件建立、複製初始化等場合。
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)
};
注意:若類別自行定義任何建構函式,編譯器不再自動產生預設建構函式。若仍需無參數建構,必須額外提供 (或使用預設參數)。
形式: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; }
// ... 指派運算子、移動語意等 ...
};
名稱:~ClassName()。無參數、無傳回型別、不可多載 (一個類別只能有一個)。
delete 動態物件、程式結束銷毀全域/靜態物件。virtual,確保透過基底指標 delete 衍生物件時正確呼叫衍生解構函式。即:建構順序與解構順序完全相反。
當類別包含類別型別成員 (成員物件) 時,建構函式必須透過初始化清單 呼叫其建構函式,賦值方式 (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 已初始化
}
};
const MyClass obj(args); // 必須初始化,不可修改
obj.NonConstMethod(); // 錯誤:無法透過 const 物件呼叫非 const 成員函式
obj.ConstMethod(); // 正確
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 成員函式。只能 在初始化清單中初始化,不可在函式本體賦值:
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; } // 錯誤:編譯失敗
};
::ClassName::MemberName 指明隸屬。ClassName::member 或 this->member 區分。obj.member 或 ptr->member。
#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/參考成員 | 只能在初始化清單初始化 |