问题背景:
将任意一个平面图形(如长方形、三角形、圆形等)沿其法线方向平移一定长度,它所扫过的空间区域为一个柱体。例如,长方形、圆形和三角形所形成的柱体分别如图(a)(b)©所示。
实验题:
柱体的体积 和表面积 计算公式分别为:
式中, 和 分别为柱体的底面积和底面周长。
请用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:
存在的问题:
- 注意cmath头文件
可行性优化:
- 使用构造函数对类对象进行初始化,同时注意纯虚函数的构造函数使用时的问题