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. 呼叫無參建構函數 -> 連結器找不到定義 -> 報錯
...
}
Box(); 僅是**宣告**,沒有**定義** (沒有函數體 {})。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。