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

C++ 類別核心三大函式:建構、解構與指派詳解(上)

     編輯:VC 教學

前言:看似簡單,實則暗藏殺機

建構函式、解構函式、指派函式是每個類別最基礎的成員函式。它們平凡到讓人容易掉以輕心,實則如同「沒有蓋子的下水道」般危險。每個類別僅有一個解構函式和一個指派函式,但可擁有多個建構函式(含一個複製建構函式)。

若程式設計師不主動撰寫,C++ 編譯器會自動生成四個預設版本:

A();                 // 預設無參數建構函式
A(const A& a);       // 預設複製建構函式
~A();                // 預設解構函式
A& operator=(const A& a); // 預設指派函式

為何仍需自行實作?

  1. 放棄初始化與清理控制權:使用預設無參數建構/解構函式,等於放棄了自主「初始化」與「清除」的機會,辜負了 Stroustrup 的設計初衷。
  2. 位拷貝而非值拷貝:預設複製建構與指派函式採用「位元逐位拷貝」。若類別內含指標成員,極易導致記憶體洩漏、雙重釋放、懸空指標等嚴重錯誤。

若有人宣稱撰寫這三大函式「很簡單、不用動腦」,其認識顯然尚淺,功力有待精進。

案例類別:String 設計

本章以 String 類別為例,深入剖析常被教科書忽略的關鍵細節:

class String {
public:
    String(const char* str = NULL);      // 一般建構函式
    String(const String& other);         // 複製建構函式
    ~String();                           // 解構函式
    String& operator=(const String& other); // 指派函式
private:
    char* m_data; // 動態配置的字串緩衝區
};

9.1 建構與解構的由來

C++ 編譯器具備嚴格的型別安全檢查,能找出大多數語法錯誤。但「通過編譯 ≠ 無錯誤」。經驗顯示,許多難以察覺的 Bug 源於變數未正確初始化或清理,而這兩項工作極易被遺忘。

Stroustrup 的解決方案極具智慧:

  • 將初始化工作放入建構函式,物件建立時自動執行。
  • 將清理工作放入解構函式,物件銷毀時自動執行。

如此便不必擔心遺忘初始化與清理。

命名慣例與特殊性質

  • 命名:建構函式與類別同名;解構函式在類別名前加 ~ 前綴,象徵「相反操作」。
  • 無回傳型別:建構/解構函式不可宣告回傳型別(甚至不能是 void)。它們的使命單純如「出生與死亡」,若有回傳值編譯器將無所適從。

(參考文獻:Eckel, Thinking in C++, pp. 55-56)

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved