代碼中 Triangle 繼承自 Point,但 Point 僅提供帶參數的構造函數 Point(int, int),未提供默認構造函數。當 Triangle 的構造函數未顯式調用基類構造函數時,編譯器嘗試隱式調用 Point() 失敗,報錯 no matching function for call to 'Point::Point()'。
class Point {
public:
Point(int xx, int yy) { x = xx; y = yy; }
private:
int x, y;
};
class Triangle : public Point { // 繼承關係設計不當
public:
Triangle(Point p1, Point p2, Point p3) : p1(p1), p2(p2), p3(p3) {} // 缺少基類初始化
private:
Point p1, p2, p3;
};
在 Triangle 構造函數初始化列表中顯式調用基類構造函數:
Triangle(Point p1, Point p2, Point p3) : Point(0, 0), p1(p1), p2(p2), p3(p3) {}
「三角形繼承自點」違反里氏替換原則 (LSP)。三角形 不是 一種點,而是 由 三個點組成。正確設計應使用組合而非繼承:
class Triangle {
private:
Point p1, p2, p3;
public:
Triangle(Point p1, Point p2, Point p3) : p1(p1), p2(p2), p3(p3) {}
// 計算面積、周長等方法
};
組合模式更符合現實語義,避免繼承帶來的耦合與初始化問題。