(学习体验多态)Shape类家族

任务描述

本关任务:阅读代码,完善shape类家族,按继承派生关系,依次为Shape --> Point-->Circle -->Cyliner , 其中 A-->B表示B public 继承了A。注意,按下面要求做,不允许自己开放接口,即类的定义中不允许随意添加成员函数。

实训要求:

  1. 修改shape.h中类的定义,使得Shape类为抽象类,其中成员函数getArea和getVolume应定义为虚函数,成员函数getName和Print已定义为纯虚函数。注意,不允许自己添加成员函数。
  2. 根据注释,学习并理解shape.cpp中Shape类 Point类和Circle 类的实现,复习派生类的构造函数,继承体系中成员函数的访问控制,以及类型兼容规则
  3. 根据注释要求,在shape.cpp中补充实现Cylinder类的成员函数 getArea(), getVolume()
  4. 根据注释,学习理解main.cpp中以下两个通用函数的功能和意义
    1. void DrawAll( Shape * );
    2. void DrawViaRef( Shape &baseClassRef );`
  5. 根据注释要求,在main.cpp中指定位置补充代码

在此处可以选择文件

,

测试说明

平台会对你编写的代码进行测试:

测试输入:3 3 10 10 预期输出:

 
  1. Virtual function calls made off base-class pointers:
  2. I am Point: [7, 11]
  3. my area is 0.00
  4. my volume is 0.00
  5. I am Circle: center is [22, 8]; radius is 3.50
  6. my area is 38.48
  7. my volume is 0.00
  8. I am Cylinder: center is [10, 10]; radius is 3.30; height is 10.00
  9. my area is 275.66
  10. my volume is 342.12
  11. call DrawViaRef(cir2) cir2 was constructed by copying cir1
  12. Circle: center is [22, 8]; radius is 3.50
  13. area is 38.48
  14. volume is 0.00
  15. call DrawViaRef(cy2)
  16. Cylinder: center is [3, 3]; radius is 10.00; height is 10.00
  17. area is 1256.32
  18. volume is 3141.59
  19. Cylinder cy2's base area, surface area and volume are: 314.16 1256.32 3141.59

开始你的任务吧,祝你成功!

答案

main.cpp

 #include <iostream>
 #include <iomanip>
 using namespace std;
 #include "shape.h"

 // 体会通过基类指针调用虚函数实现多态
 // 该函数将输出参数baseClassPtr指向的对象的形状名称,对象信息,面积和体积
 void DrawAll(Shape * baseClassPtr);

 // 学习体会通过基类的引用调用虚函数 实现多态,形参baseClassRef的类型是Shape&
 // 输出参数baseClassRef引用的对象的形状名称,对象信息,面积和体积
 void DrawViaRef(Shape & baseClassRef);

 int main()
 {
 // set floating-point number format
 cout << fixed << setprecision(2);

 Point p(7, 11); // create a Point
Circle cir1(22, 8, 3.5); // create a Circle
 Cylinder cy1(10, 10, 3.3, 10); // create a Cylinder


 // create vector of three base-class pointers
 Shape * shapePtr[3];
 // aim shapePtr[0] at derived-class Point object
 shapePtr[0] = &p;

// aim shapePtr[1] at derived-class Circle object
shapePtr[1] = &cir1;
 // aim shapePtr[2] at derived-class Cylinder object
 shapePtr[2] = &cy1;


 cout << "\nVirtual function calls made off "
 << "base-class pointers:\n\n";

 for (int i = 0; i < 3; i++)
 DrawAll(shapePtr[i]);

 double x, y, r, h;
 cin >> x >> y >> r >> h;
 Circle cir2(cir1); // cir2通过复制cir1构造,若没有自定义复制构造函数,系统会自动生成复制
 Cylinder cy2;


//将x y r h的值分别赋给cy2的 x y radius height, 输出cy的底面积,表面积和体积
 cy2.setPoint(x, y);
 cy2.setRadius(r);
 cy2.setHeight(h);

 //函数DrawViaReference采用传引用的方式,传递的是基类的引用
 //请观察当实参为circle对象和Cylinder对象时,函数的执行结果分别是什么,体会多态的含义
 cout << "call DrawViaRef(cir2)  cir2 was constructed by copying cir1\n";
 DrawViaRef(cir2);
 cout << "call DrawViaRef(cy2)\n";
 DrawViaRef(cy2);

 cout << "Cylinder cy2's base area, surface area and volume are: ";
 /*****Begin*****/
 cout << cy2.Circle::getArea() << ' ' << cy2.getArea() << ' ' << cy2.getVolume() << endl;
 /*****End*****/

 return 0;


 } // end main

 // 通过基类指针调用虚函数
 // 该函数将输出参数baseClassPtr指向的对象的形状名称,对象信息,面积和体积
 void DrawAll(Shape * baseClassPtr)
 {
 cout << "I am " << baseClassPtr->getName() << ": ";

 baseClassPtr->print();

cout << "\n my area is " << baseClassPtr->getArea()
     << "\n my volume is " << baseClassPtr->getVolume()
     << "\n\n";

 } // end function virtualViaPointer

 // 通过基类的引用调用虚函数 实现动态联编,形参baseClassRef的类型是Shape&
 // 输出参数baseClassRef引用的对象的形状名称,对象信息,面积和体积
 void DrawViaRef(Shape& baseClassRef)
{
 cout << baseClassRef.getName() << ": ";

 baseClassRef.print();

 cout << "\narea is " << baseClassRef.getArea()
 << "\nvolume is " << baseClassRef.getVolume() << "\n\n";

 } // end function DrawViaRef

shape.cpp

 // Fig. 10.13: shape.cpp
 // Shape class member-function definitions.
 #include <iostream>
 #include "shape.h" // Shape class definition
 using namespace std;

 // return area of shape; 0.0 by default
 double Shape::getArea()
 {
 return 0.0;
 } // end function getArea

 // return volume of shape; 0.0 by default
 double Shape::getVolume()
 {
 return 0.0;
 } // end function getVolume

 // default constructor
 Point::Point(int xValue, int yValue)
 : x(xValue), y(yValue)
 {
 // empty body
 } // end Point constructor


//重新定义纯虚函数getName,返回"Point"
 string Point::getName()
 {
 return "Point";
 } // end function getName

//重新定义纯虚函数print: 输出点的信息
 void Point::print()
 {
 cout << '[' << x << ", " << y << ']';
 } // end function print

 // Circle的缺省构造函数
 Circle::Circle(int xValue, int yValue, double radiusValue)
 : Point(xValue, yValue) // call base-class constructor
 {

	 radius = radiusValue;

 } // end Circle constructor


 // 计算并返回周长
 double Circle::getCircumference()
 {
 return 6.28 * radius;
 } // end function getCircumference

 //重新定义虚函数getArea,返回圆的面积
 double Circle::getArea()
{
 return 3.14159 * radius * radius;
 } // end function getArea

 //重新定义纯虚函数getName,返回"Circle"
 string Circle::getName()
{
 return "Circle";
 } // end function getName

 //重新定义纯虚函数Print,输出圆的信息
 void Circle::print()
 {
 cout << "center is ";
 Point::print(); // invoke Point's print function
 cout << "; radius is " << radius;
 } // end function print
 ///Cylinder/
 //*************Begin**************/
 // 缺省构造函数
 Cylinder::Cylinder(int xValue, int yValue, double radiusValue, double heightValue)
 : Circle(xValue, yValue, radiusValue)
 {
 height = heightValue;
 } // end Cylinder constructor


 //重新定义虚函数getArea,返回圆柱体的表面积
 double Cylinder::getArea()
 {
 return 2 * Circle::getArea() + getCircumference() * height;

 } // end function getArea

 //重新定义虚函数getVolume: 返回圆柱体的体积
 double Cylinder::getVolume()
 {
 return Circle::getArea() * height;
 } // end function getVolume

 /*****************End*********/

 //重新定义纯虚函数getName,返回"Cylinder"
string Cylinder::getName()
{
	return "Cylinder";
} // end function getName

 //重新定义纯虚函数getName,输出圆柱体的信息
 void Cylinder::print()
 {
 Circle::print(); // code reuse
 cout << "; height is " << height;
 } // end function print

shape.h

 #ifndef SHAPE_H_INCLUDED
 #define SHAPE_H_INCLUDED
 #include <string>
 using namespace std;

 /********** Begin **********/
 class Shape {
 public:
 virtual double getArea();// 虚函数 返回面积
 virtual double getVolume(); // 虚函数 返回体积

 // 纯虚函数,必须在派生类中被重写
 virtual string getName() = 0; // return shape name
 virtual void print() = 0; // output shape


}; // end class Shape

 class Point : public Shape {
public:
 Point(int x = 0, int y = 0); // 缺省构造函数
 void setPoint(int x, int y) { this->x = x; this->y = y; }// set x y坐标

 virtual string getName();// 返回形状名称,即"Point"
 virtual void print(); // 输出Point对象的信息

 private:
int x; // x part of coordinate pair
int y; // y part of coordinate pair

}; // end class Point

 class Circle : public Point {
public:
 // default constructor
 Circle(int = 0, int = 0, double = 0.0);


 void setRadius(double r) { radius = r; } // 设置半径
 double getCircumference(); // 返回周长
 virtual double getArea(); //返回圆的面积
 virtual string getName();// 返回形状名称,即"Circle")
virtual void print(); // 输出Circle对象的信息

 private:
	double radius; // Circle's radius

}; // end class Circle

 class Cylinder : public Circle {
 public:
 // default constructor
 Cylinder(int = 0, int = 0, double = 0.0, double = 0.0);

 void setHeight(double h) { height = h; } // 设置圆柱体的高度
 virtual double getArea(); //返回圆柱体的表面积
 virtual double getVolume(); //返回圆柱体的体积

virtual string getName(); // 返回形状名称,即"Cylinder"
 virtual void print(); // 输出Cylinder对象的信息

 private:
double height; // Cylinder's height

}; // end class Cy

 /********** End **********/
#endif // SHAPE_H_INCLUDED

用于本人在大学期间的学习记录

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值