#381. 四边形继承练习

本文展示了如何使用C++编写类结构,包括Quadrilateral(四边形)、Parallelogram(平行四边形)和Rectangle(矩形),实现计算这些图形的面积和周长,并通过继承和条件判断优化代码。作者还提到了对面向对象编程中继承概念的应用和代码优化建议。
摘要由CSDN通过智能技术生成

太爽了

甚至还现学了叉积判断线段是否相交和求面积的方法

先给出我的代码:

#include <iostream>
#include <vector>
#include <iomanip>
#include <cmath>

using namespace std;

//下面需要补充多个类的声明及实现代码
const double EPS = 1e-6;
struct Point{
    double x, y;
    Point(double x, double y):x(x), y(y){}
};

class Quadrilateral{
public:
    Quadrilateral(){}
    Quadrilateral(vector<Point> &vertices):p(vertices){}
    double getArea();
    double getPerimeter();
    bool verify();
protected:
    vector<Point> p;//四边形的四个顶点,从任一顶点出发按顺序存放
};

class Parallelogram:protected Quadrilateral{
public:
    Parallelogram(){}
    Parallelogram(vector<Point> &vertices){Quadrilateral::p = vertices;}
    double getArea();
    double getPerimeter();
    bool verify();
};

class Rectangle:protected Parallelogram{
public:
    Rectangle(){}
    Rectangle(vector<Point> &vertices){Quadrilateral::p = vertices;}
    double getArea();
    double getPerimeter();
    bool verify();
};

bool Quadrilateral::verify(){
    {
        double x1 = p[2].x - p[0].x, y1 = p[2].y - p[0].y;
        double x2 = p[1].x - p[0].x, y2 = p[1].y - p[0].y;
        double x3 = p[3].x - p[0].x, y3 = p[3].y - p[0].y;
        if((x1 * y2 - x2 * y1) * (x1 * y3 - x3 * y1) >= 0) return false;
    }
    {
        double x1 = p[3].x - p[1].x, y1 = p[3].y - p[1].y;
        double x2 = p[0].x - p[1].x, y2 = p[0].y - p[1].y;
        double x3 = p[2].x - p[1].x, y3 = p[2].y - p[1].y;
        if((x1 * y2 - x2 * y1) * (x1 * y3 - x3 * y1) >= 0) return false;
    }
    return true;
}
double Quadrilateral::getArea(){
    if(verify()){
        double S1 = 0.5 * fabs((p[1].x - p[0].x) * (p[2].y - p[0].y) - (p[1].y - p[0].y) * (p[2].x - p[0].x));
        double S2 = 0.5 * fabs((p[3].x - p[0].x) * (p[2].y - p[0].y) - (p[3].y - p[0].y) * (p[2].x - p[0].x));
        return S1 + S2;
    }
    else return 0.0;
}
double Quadrilateral::getPerimeter(){
    if(verify()){
        double l1 = sqrt(pow(p[1].x - p[0].x, 2.0) + pow(p[1].y - p[0].y, 2.0));
        double l2 = sqrt(pow(p[2].x - p[1].x, 2.0) + pow(p[2].y - p[1].y, 2.0));
        double l3 = sqrt(pow(p[3].x - p[2].x, 2.0) + pow(p[3].y - p[2].y, 2.0));
        double l4 = sqrt(pow(p[0].x - p[3].x, 2.0) + pow(p[0].y - p[3].y, 2.0));
        return l1 + l2 + l3 + l4;
    }
    else return 0.0;
}

bool Parallelogram::verify(){
    if(Quadrilateral::verify()){
        double l1 = sqrt(pow(p[1].x - p[0].x, 2.0) + pow(p[1].y - p[0].y, 2.0));
        double l2 = sqrt(pow(p[2].x - p[1].x, 2.0) + pow(p[2].y - p[1].y, 2.0));
        double l3 = sqrt(pow(p[3].x - p[2].x, 2.0) + pow(p[3].y - p[2].y, 2.0));
        double l4 = sqrt(pow(p[0].x - p[3].x, 2.0) + pow(p[0].y - p[3].y, 2.0));
        if(fabs(l1 - l3) <= EPS && fabs(l2 - l4) <= EPS) return true;
        else return false;
    }
    else return false;
}
double Parallelogram::getArea(){
    if(verify()) return Quadrilateral::getArea();
    else return 0.0;
}
double Parallelogram::getPerimeter(){
    if(verify()) return Quadrilateral::getPerimeter();
    else return 0.0;
}

bool Rectangle::verify(){
    if(Parallelogram::verify()){
        double l1 = sqrt(pow(p[2].x - p[0].x, 2.0) + pow(p[2].y - p[0].y, 2.0));
        double l2 = sqrt(pow(p[3].x - p[1].x, 2.0) + pow(p[3].y - p[1].y, 2.0));
        if(fabs(l1 - l2) <= EPS) return true;
        else return false;
    }
    else return false;
}
double Rectangle::getArea(){
    if(verify()) return Quadrilateral::getArea();
    else return 0.0;
}
double Rectangle::getPerimeter(){
    if(verify()) return Quadrilateral::getPerimeter();
    else return 0.0;
}

//填空结束
 

int main()
{
    vector<Point> vertices;
    for (int i=0;i<4;i++){
        double x,y;
        cin>>x>>y;
        Point p(x,y);
        vertices.push_back(p);
    }

    Quadrilateral q(vertices);
    Parallelogram pa(vertices);
    Rectangle r(vertices);

    cout<<fixed<<setprecision(2);

    cout<<(q.verify()?1:0)<<endl;
    cout<<q.getArea()<<endl;
    cout<<q.getPerimeter()<<endl;

    cout<<(pa.verify()?1:0)<<endl;
    cout<<pa.getArea()<<endl;
    cout<<pa.getPerimeter()<<endl;

    cout<<(r.verify()?1:0)<<endl;
    cout<<r.getArea()<<endl;
    cout<<r.getPerimeter()<<endl;

    return 0;
}

当然以上是老师给的原文件填上我的答案之后的,我填的地方有注释标注的,很明显

说实话第一次用继承,虽然上次有用过,但是没那么深入

代码还有可以改进的地方,像在求面积和周长的时候,可以用一个值记录,以及一个值记录是否判断过,避免重复判断

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值