首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 類編譯錯誤:undefined reference to `Box::Box()` 完整解析

     編輯:程式設計綜合問答

錯誤訊息

undefined reference to `Box::Box()'
ld returned 1 exit status

代碼還原

class Box {
public:
    double length, height, width;
    int d;
    Box(); // 1. 宣告了無參建構函數
    Box(double l, double h, double w) { ... } // 2. 定義了有參建構函數
    double volume() { ... }
};

int main() {
    Box firstBox(2.0, 4.0, 6.0); // 呼叫有參建構函數 OK
    Box smallBox; // 3. 呼叫無參建構函數 -> 連結器找不到定義 -> 報錯
    ...
}

核心原因:C++ 建構函數規則

  1. 使用者宣告任何建構函數 (含有參) → 編譯器**不再自動生成**預設無參建構函數。
  2. 程式碼中 Box(); 僅是**宣告**,沒有**定義** (沒有函數體 {})。
  3. Box smallBox; 需要呼叫無參建構函數 → 連結階段找不到符號 Box::Box() → Linker Error (LNK2019 / undefined reference)。

三種修正方案

方案一:補上定義 (最直接修復現有代碼)

class Box {
public:
    // ...
    Box() {} // 內聯定義:空函數體,成員變數將未初始化 (含亂碼)
    // 或
    Box() : length(0), height(0), width(0), d(0) {} // 推薦:初始化列表給預設值
    // ...
};

方案二:使用 = default (C++11 現代寫法)

class Box {
public:
    // ...
    Box() = default; // 明確要求編譯器生成預設建構函數 (成員若有類類型會遞迴預設建構,基本型型別不初始化)
    // ...
};

方案三:刪除宣告,依賴編譯器隱式生成 (前提:不需要自訂邏輯)

class Box {
public:
    // 刪除 Box(); 這行宣告
    Box(double l, double h, double w) { ... } // 保留有參
    // ...
};

注意: 若類中有 const 成員、reference 成員、或無預設建構函數的類對象成員,編譯器**無法**隱式生成無參建構函數,必須採用方案一或二顯式定義並初始化這些成員。

延伸知識:成員變數初始化最佳實踐

class Box {
    double length = 0.0; // C++11 類內初始化 (推薦,簡潔)
    double height = 0.0;
    double width = 0.0;
    int d = 0;
public:
    Box() = default; // 直接用預設值
    Box(double l, double h, double w) : length(l), height(h), width(w) {} // 委派初始化
    // ...
};

總結

「宣告 ≠ 定義」。 你在類中寫 Box(); 只是告訴編譯器「有這個函數」,卻沒給它肉 (函數體)。連結器負責找肉,找不到就報 undefined reference。
**鐵律**:寫了有參建構函數,若仍需無參建構,必須**顯式定義** ( Box() {} 或 Box() = default ),且建議配合類內成員初始化或初始化列表給予合理預設值,避免使用未初始化記憶體導致邏輯 Bug。

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