实验七 多态性与虚函数

问题背景:
将任意一个平面图形(如长方形、三角形、圆形等)沿其法线方向平移一定长度,它所扫过的空间区域为一个柱体。例如,长方形、圆形和三角形所形成的柱体分别如图(a)(b)(c)所示。
实验题:
柱体的体积 和表面积 计算公式分别为:

式中, 和 分别为柱体的底面积和底面周长。
请用C++语言编写面向对象程序,实现柱体体积和表面积的计算(圆柱和四棱柱为必做内容,三棱柱为选做内容)。例如底面半径为2、高为4的圆柱,体积为50.27,表面积为75.40;以长为3、宽为2的长方形为底面,高为5的四棱柱,体积为30,表面积为62。
提示:
注意:以下定义的类中,若未给出构造函数、析构函数及输出函数,请根据需要添加。
1、 定义一个描述平面图形的抽象类Plane,其成员函数如下表:

函数名 访问权限 形参 返回值 功能 虚函数?
area public void float 求面积 纯虚函数
girth public void float 求周长 纯虚函数

2、定义一个描述柱体的类Body:

(1) 类Body的成员变量如下表:

变量名 访问权限 类型 含义
pbasic private Plane * 指向柱体的底面图形
high private float 给出柱体的高

(2) 类Body的成员函数如下表:

函数名 访问权限 形参 返回值 功能 虚函数?
volume public void float 求体积 否
surfaceArea public void float 求表面积 否
3、从抽象类Plane派生出具体类(如长方形类Rectangle、圆形类Circle和三角形类triangle),根据实际情况,覆盖基类Plane的纯虚函数area和girth,如下表。

函数名 访问权限 形参 返回值 功能 虚函数?
area public void float 求面积 自动为虚函数
girth public void float 求周长 自动为虚函数

(1) 长方形类Rectangle的成员变量为

变量名 访问权限 类型 含义
a private float 给出长方形的长
b private float 给出长方形的宽

(2) 圆形类Circle的成员变量为

变量名 访问权限 类型 含义
a private float 给圆形的半径

(3) 三角形类Triangle的成员变量为

变量名 访问权限 类型 含义
A private Point 给出三角形的顶点A
B private Point 给出三角形的顶点B
C private Point 给出三角形的顶点C

其中,Point为描述平面点的类,其成员变量为:

变量名 访问权限 类型 含义
x public float 给出顶点的x坐标
y public float 给出顶点的y坐标

附代码
!!!编译环境 DevC++ 5.11 TDM-GCC 4.9.2 64-Bit Release
头文件 iquery.h

#ifndef  _IQUERY_H
#define _IQUERY_H 1
    using namespace std;
    class Plane
    {
        public:
            virtual float area() const =0;
            virtual float girth() const =0;
    }
    class Body
    {
        public:
            float volume();
            float surfaceArea();
            void setpb(Plane *p);
            void sethigh();
        private:
            Plane *pbasic;
            float high;
    };

    class Point
    {
        public:
            void setpoint();
            float x;
            float y;
    };
    class Rectangle: public Plane
    {
        public:
            void setrec();
            virtual float area()const;
            virtual float girth()const;
        private:
            float a;
            float b;
    };
    class Circle: public Plane
    {
        public:
            void setcir();
            virtual float area()const;
            virtual float girth()const;
        private:
            float a;
    };
    class Triangle: public Plane
    {
        public:
            void settri();
            virtual float area()const;
            virtual float girth()const;
        private:
            Point A;
            Point B;
            Point C;
    };
#endif

头文件实现文件 iquery,cpp

#include <iostream>
#include "string"
#include "iquery.h"
#include "iomanip"
#include "cmath" 
using namespace std; 
float Body::volume(){
    return pbasic->area()*high;
}
float Body::surfaceArea(){
    return 2*pbasic->area()+pbasic->girth()*high;
}
void Body::setpb(Plane *p){
    pbasic=p;
}
void Body::sethigh(){
    cin >>high;
}
void Rectangle :: setrec(){
    cout << "输入四棱柱底面的长:" ;
    cin >>a; cout<<endl;
    cout << "输入四棱柱底面的宽:" ;
    cin >> b; cout <<endl;
}
float Rectangle :: area()const{
    return a*b;
}
float Rectangle ::girth()const{
    return 2*(a+b);
}
void Circle :: setcir(){
    cout <<"输入圆柱的半径:" ;
    cin >> a;cout<<endl;
}
float Circle :: area()const{
    return 3.14159*a*a;
}
float Circle :: girth()const{
    return 2*3.14159*a;
}
void Point ::setpoint(){
    cin >> x >>y;
}
void Triangle :: settri(){
    cout << "输入三棱柱底面顶点A的<x y>坐标:" ;
    A.setpoint();cout<<endl;
    cout << "输入三棱柱底面顶点B的<x y>坐标:" ;
    B.setpoint();cout<<endl;
    cout << "输入三棱柱底面顶点C的<x y>坐标:" ;
    C.setpoint();cout<<endl;
}
float Triangle :: area()const{
    float m;
    m=A.x*B.y+A.y*C.x+B.x*C.y-A.x*C.y-A.y*B.x-B.y*C.x;
    if(m>0) return m/2;
    else return -m/2;
}
float Triangle :: girth()const{
    return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y))+sqrt((C.x-B.x)*(C.x-B.x)+(C.y-B.y)*(C.y-B.y))+sqrt((A.x-C.x)*(A.x-C.x)+(A.y-C.y)*(A.y-C.y));
}

源码 main.cpp

#include <iostream>
#include "string"
#include "iquery.h"
#include "iomanip"
#include "cmath" 

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
int main(int argc, char** argv) {
    Body body;
    Circle c;
    Rectangle r;
    Triangle t;
    body.setpb(&c);
    c.setcir();
    cout << "输入圆柱体的高:";
    body.sethigh();
    cout<<"圆柱体的体积为:"<<body.volume()<<endl;
    cout<<"圆柱体的表面积为:"<<body.surfaceArea()<<endl;
    cout<<endl;
    body.setpb(&r);
    r.setrec();
    cout <<"输入四棱柱的高:";
    body.sethigh();
    cout<<"四棱柱的体积为:"<<body.volume()<<endl;
    cout<<"四棱柱的表面积为:"<<body.surfaceArea()<<endl;
    cout<<endl;
    body.setpb(&t);
    t.settri();
    cout << "输入三棱柱的高:";
    body.sethigh();
    cout<<"三棱柱的体积为:"<<body.volume()<<endl;
    cout<<"三棱柱的表面积为:"<<body.surfaceArea()<<endl; 
    return 0; 
}

注:
已经出现过的error:

存在的问题:

  1. 注意cmath头文件

可行性优化:

  1. 使用构造函数对类对象进行初始化,同时注意纯虚函数的构造函数使用时的问题

猜你喜欢

转载自blog.csdn.net/qq_40724028/article/details/80278025