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

C++ 多態與繼承:幾何形狀類層次結構重構修正

     編輯:程式設計綜合問答

原代碼主要問題

  1. Cone 構造函數調用錯誤:Cylinder(r), Cylinder(h) 嘗試雙重調用基類構造函數,且參數不匹配
  2. Sphere 繼承設計缺陷:Sphere 繼承 Circle 但重新定義 radius 導致遮蔽,且 4/3 整除得 1
  3. Cuboid 未繼承 Shape:導致無法多態使用,且方法內使用未聲明變量 l、w、h
  4. Rectangle 未實現所有純虛函數:缺少 volume()、surface() 導致抽象類無法實例化
  5. 主函數邏輯錯誤:switch 語句結構錯亂,case 不在 switch 內,cout 連寫語法錯誤

修正後的類層次結構

基類 Shape

class Shape {
public:
    virtual double area() = 0;
    virtual double volume() = 0;
    virtual double surface() = 0;
    virtual ~Shape() = default; // 虛析構函數
};

二維形狀

class Circle : public Shape {
protected:
    double radius;
public:
    Circle(double r) : radius(r) {}
    double area() override { return PI * radius * radius; }
    double volume() override { return 0; }
    double surface() override { return 0; }
};

class Rectangle : public Shape {
protected:
    double width, height;
public:
    Rectangle(double w, double h) : width(w), height(h) {}
    double area() override { return width * height; }
    double volume() override { return 0; }
    double surface() override { return 0; }
};

三維形狀(組合優於繼承)

// 圓柱:組合圓形底面 + 高度
class Cylinder : public Shape {
    Circle base;
    double height;
public:
    Cylinder(double r, double h) : base(r), height(h) {}
    double area() override { return base.area(); } // 底面積
    double volume() override { return base.area() * height; }
    double surface() override { return 2 * base.area() + 2 * PI * radius * height; }
};

// 球體:獨立實現
class Sphere : public Shape {
    double radius;
public:
    Sphere(double r) : radius(r) {}
    double area() override { return 0; } // 球無「面積」概念,或視為表面積
    double volume() override { return (4.0/3.0) * PI * radius * radius * radius; }
    double surface() override { return 4 * PI * radius * radius; }
};

// 圓錐:組合圓形底面 + 高度
class Cone : public Shape {
    Circle base;
    double height;
public:
    Cone(double r, double h) : base(r), height(h) {}
    double area() override { return base.area(); }
    double volume() override { return (1.0/3.0) * base.area() * height; }
    double surface() override { 
        double l = sqrt(base.radius * base.radius + height * height); // 斜高
        return base.area() + PI * base.radius * l; 
    }
};

// 長方體:組合矩形底面 + 高度
class Cuboid : public Shape {
    Rectangle base;
    double height;
public:
    Cuboid(double l, double w, double h) : base(l, w), height(h) {}
    double area() override { return base.area(); }
    double volume() override { return base.area() * height; }
    double surface() override { 
        return 2 * (base.width * base.height + base.width * height + base.height * height); 
    }
};

主程序邏輯修正

int main() {
    while (true) {
        cout << "1.圓形 2.長方形 3.長方體 4.圓柱 5.圓錐 6.球體 0.退出\n";
        int choice; cin >> choice;
        if (choice == 0) break;
        
        Shape* shape = nullptr;
        double r, h, w, l;
        
        switch (choice) {
            case 1:
                cout << "半徑: "; cin >> r;
                shape = new Circle(r);
                cout << "面積: " << shape->area() << endl;
                break;
            case 2:
                cout << "寬 高: "; cin >> w >> h;
                shape = new Rectangle(w, h);
                cout << "面積: " << shape->area() << endl;
                break;
            case 3:
                cout << "長 寬 高: "; cin >> l >> w >> h;
                shape = new Cuboid(l, w, h);
                cout << "表面積: " << shape->surface() << " 體積: " << shape->volume() << endl;
                break;
            case 4:
                cout << "半徑 高: "; cin >> r >> h;
                shape = new Cylinder(r, h);
                cout << "表面積: " << shape->surface() << " 體積: " << shape->volume() << endl;
                break;
            case 5:
                cout << "半徑 高: "; cin >> r >> h;
                shape = new Cone(r, h);
                cout << "表面積: " << shape->surface() << " 體積: " << shape->volume() << endl;
                break;
            case 6:
                cout << "半徑: "; cin >> r;
                shape = new Sphere(r);
                cout << "表面積: " << shape->surface() << " 體積: " << shape->volume() << endl;
                break;
            default:
                cout << "無效選項\n";
                continue;
        }
        delete shape; // 釋放內存
        system("pause");
        system("cls");
    }
    return 0;
}

設計原則總結

  • 組合優於繼承:三維形狀組合二維底面,而非繼承(球不是圓,圓柱不是圓)
  • 虛析構函數:基類析構函數必須聲明為 virtual
  • override 關鍵字:C++11 明確標記重寫,編譯器檢查簽名一致性
  • 浮點數除法:4.0/3.0 而非 4/3(整除)
  • RAII 原則:動態分配對象需配對 delete,或使用智能指針 unique_ptr
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved