C++ 实验七 多态性与虚函数

问题背景:
将任意一个平面图形(如长方形、三角形、圆形等)沿其法线方向平移一定长度,它所扫过的空间区域为一个柱体。例如,长方形、圆形和三角形所形成的柱体分别如图(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:

存在的问题:

  1. 注意cmath头文件

可行性优化:

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

欢迎访问陈风的个人博客

  • 26
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值