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

VC++ 深度解析 C++ 建構函數:自動初始化與預設建構函數規則

     編輯:VC 教學

前言

建構函數是 C++ 類別自動初始化的核心機制。本文透過實例演示:未初始化成員變數導致隨機值、手動 init() 易忘記呼叫、建構函數自動執行初始化、編譯器提供預設建構函數的三大條件,並引用 ANSI C++ ISO 標準釐清常見誤區。

問題現場:未初始化的隨機值

#include 
using namespace std;

class Point {
public:
    int x, y;
    void output() { cout << x << endl << y << endl; }
};

int main() {
    Point pt;      // 未初始化
    pt.output();   // 輸出兩個巨大隨機負數 (堆疊殘留值)
}

原因:pt 建立時,編譯器只配置記憶體,不自動清零。成員 x, y 含隨機位元模式。

嘗試 1:手動 init() 函數

class Point {
public:
    int x, y;
    void init() { x = 0; y = 0; }
    void output() { cout << x << endl << y << endl; }
};

int main() {
    Point pt;
    pt.init();     // 程式設計師必須記得呼叫
    pt.output();   // 輸出 0, 0
}

缺點:易忘記呼叫、無法保證物件一出生即處於合法狀態。

解決方案:建構函數

class Point {
public:
    int x, y;
    Point() {       // 建構函數:無回傳型別、名稱與類別同名
        x = 0; y = 0;
    }
    void output() { cout << x << endl << y << endl; }
};

int main() {
    Point pt;       // 自動呼叫 Point::Point()
    pt.output();    // 保證輸出 0, 0
}

特性:

  • 名稱 = 類別名,無回傳型別 (連 void 都不能寫)。
  • 物件定義瞬間自動呼叫,確保「資源取得即初始化」(RAII)。
  • 可多載 (參數不同),支援多種初始化方式。

編譯器預設建構函數:三大觸發條件 (ISO C++ 標準)

若類別**未宣告任何建構函數**,編譯器**僅在下列三種情況**合成預設建構函數:

  1. 擁有虛擬函數或虛擬基類:需初始化 vptr/vbptr。
  2. 基類有建構函數 (使用者定義或編譯器合成):需呼叫基類建構函數。
  3. 非靜態成員物件有建構函數:需初始化成員子物件。

除此之外 (如純資料類別 struct A { int x; };),**編譯器不合成**預設建構函數,物件行為同 malloc 未初始化記憶體。

定義任何建構函數 → 編譯器不再提供預設

class Point {
public:
    Point(int a, int b) { x = a; y = b; } // 使用者定義帶參數建構函數
    int x, y;
};

int main() {
    Point pt;     // 編譯錯誤:無預設建構函數
    Point pt2(1,2); // OK
}

對策:若需無參數建構,必須**額外定義** Point() { x=0; y=0; }。

建構函數最佳實踐

  • 成員初始化清單:Point(int a, int b) : x(a), y(b) {} 效率更高、可初始化 const/reference 成員。
  • explicit:單參數建構函數加 explicit 防止隱含轉換。
  • 委派建構 (C++11):Point() : Point(0,0) {} 避免重複程式碼。
  • 預設參數:Point(int a=0, int b=0) 合併無參與帶參版本。

總結

建構函數是 C++ 保證物件「生而有效」的關鍵。理解編譯器合成預設建構函數的**三大條件**,能避免「以為有預設建構函數實則無」的編譯/執行期錯誤。善用初始化清單、explicit、委派建構,寫出高效、安全的 C++ 程式碼。

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