基類 `C` 有帶參構造函數 `C(float r, float h)` 初始化 `Radius`、`high`。派生類 `Round`、`Cylinder`、`Cone` 繼承 `C` 但未定義自己的構造函數調用基類構造函數。`main()` 中直接 `Round r; r.supArea();` 導致基類成員未初始化,讀取到隨機堆疊值。
#include <iostream>
#include <cmath>
using namespace std;
const float Pi = 3.1415f;
class C {
public:
C(float r, float h) : Radius(r), high(h) {}
protected:
float Radius;
float high;
};
class Round : public C {
public:
Round(float r, float h) : C(r, h) {} // 關鍵:調用基類構造
void supArea();
void volume();
};
void Round::supArea() {
float s = 4 * Pi * pow(Radius, 2);
cout << "\n球的表面積為:" << s << endl;
}
void Round::volume() {
float v = 4 * Pi * pow(Radius, 3) / 3;
cout << "\n球的體積為:" << v << endl;
}
class Cylinder : public C {
public:
Cylinder(float r, float h) : C(r, h) {}
void supArea();
void volume();
};
void Cylinder::supArea() {
float s = 2 * Pi * pow(Radius, 2) + high * 2 * Pi * Radius;
cout << "\n圓柱的表面積為:" << s << endl;
}
void Cylinder::volume() {
float v = Pi * pow(Radius, 2) * high;
cout << "\n圓柱的體積為:" << v << endl;
}
class Cone : public C {
public:
Cone(float r, float h) : C(r, h) {}
void supArea();
void volume();
};
void Cone::supArea() {
float s = Pi * pow(Radius, 2) + Pi * Radius * high;
cout << "\n圓錐的表面積為:" << s << endl;
}
void Cone::volume() {
float v = 1.0f / 3 * Pi * pow(Radius, 2) * sqrt(pow(high, 2) - pow(Radius, 2));
cout << "\n圓錐的體積為:" << v << endl;
}
int main() {
Round r(1, 2);
r.supArea(); r.volume();
Cylinder c1(1, 2);
c1.supArea(); c1.volume();
Cone c2(1, 2);
c2.supArea(); c2.volume();
return 0;
}
| 錯誤 | 修正 |
|---|---|
| 派生類無構造函數 | 添加 `Round(float r, float h) : C(r, h) {}` 等 |
| `main()` 中 `Round r;` 無參數 | 改為 `Round r(1, 2);` 傳遞半徑、高度 |
| `Cone::volume()` 整數除法 `1/3` 為 0 | 改為 `1.0f/3` 強制浮點除法 |
| `pow(Radius, 2)` 重複計算 | 可優化為 `Radius*Radius`,非必須 |
「公有繼承後成員變隨機值」經典癥結在於派生類未正確鏈接基類構造函數。牢記「派生類構造 = 基類構造 + 自身初始化」,在初始化列表中傳遞參數,即可確保繼承體系中所有成員正確初始化。