~ClassName(),無參數、無返回值、不可多載 (一個類別僅一個)delete 動態物件
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:獨佔所有權,離開作用域自動 deletestd::shared_ptr:共享所有權,引用計數歸零自動 deletestd::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)) {}
// 無需析構函數!編譯器自動合成正確析構
};