多态图形
实验要求:
定义平面图形类Shape,至少包含虚函数(或纯虚函数)成员getPerimeter()、getArea()、getClassName()和Draw();类Line, Trapezoid, Triangle, Circle分别表示线段、梯形、三角形和圆形。Rectangle继承自Trapezoid表示矩形,Square继承自Rectangle表示正方形。重载派生类的Draw()函数完成使用*打印对应图形。
在main中使用vector《Shape *》 管理多个上述对象,并定义函数DrawShapes(const vector 《Shape *》 & v)画出所有v中的图形。
(选做)考虑使用控制台类控制输出位置,组成复杂图形(暂时未实现)
Shape.h
1 #pragma once 2 #include<iostream> 3 using namespace std; 4 #define Pi 3.14 5 class Shape 6 { 7 public: 8 Shape(void); 9 virtual float getPerimeter(); 10 virtual float getArea(); 11 virtual char* getClassName(); 12 virtual void Draw(); 13 14 ~Shape(void); 15 };
Shape.cpp
1 #include "Shape.h" 2 3 4 Shape::Shape(void) 5 { 6 } 7 float Shape::getPerimeter() 8 { 9 return 1; 10 }; 11 float Shape::getArea() 12 { 13 return 1; 14 }; 15 char* Shape::getClassName() 16 { 17 return "True"; 18 }; 19 void Shape::Draw() 20 { 21 22 }; 23 24 25 Shape::~Shape(void) 26 { 27 }
Line.h
1 #pragma once 2 #include"Shape.h" 3 class Line:public Shape 4 { 5 public: 6 Line(float l); 7 float getPerimeter(); 8 float getArea(); 9 char* getClassName(); 10 void Draw(); 11 ~Line(void); 12 private: 13 float l; 14 };
Line.cpp
1 #include "Line.h" 2 3 4 Line::Line(float x):l(x) 5 { 6 } 7 float Line::getPerimeter() 8 { 9 return l; 10 } 11 float Line::getArea() 12 { 13 return 0; 14 } 15 char* Line::getClassName() 16 { 17 return "Line"; 18 } 19 void Line::Draw() 20 { 21 for(int i=0;i<(int)l;i++) 22 cout<<"*"; 23 } 24 25 Line::~Line(void) 26 { 27 }
Circle.h
1 #pragma once 2 #include"Shape.h" 3 class Circle:public Shape 4 { 5 public: 6 Circle(float x); 7 float getPerimeter(); 8 float getArea(); 9 char* getClassName(); 10 void print_char(int x1,int x2); 11 void Draw(); 12 ~Circle(void); 13 private: 14 float semidiameter; 15 };
Circle.cpp
1 #include "Circle.h" 2 3 4 Circle::Circle(float x):semidiameter(x) 5 { 6 } 7 float Circle::getPerimeter() 8 { 9 return 2*Pi*semidiameter; 10 } 11 float Circle::getArea() 12 { 13 return Pi*semidiameter*semidiameter; 14 } 15 char* Circle::getClassName() 16 { 17 return "Circle"; 18 } 19 void Circle::print_char(int x1,int x2) 20 { 21 int i; 22 // 计算这一行的宽度,终端最多显示80列 23 int n = max(x1, x2) + 1; 24 n = n > 80 ? 80 : n; 25 for (i = 0; i < n; i++) 26 { 27 if (i == x1 || i == x2) 28 printf("*"); 29 else 30 printf(" "); 31 } 32 printf("\n"); 33 } 34 void Circle::Draw() 35 { 36 int r=(int)semidiameter; 37 int x1, x2, y; 38 int d = 2 * r; 39 int offset; 40 for(y = 0; y <= d; y++) 41 { 42 /*终端字符宽高比为2:1*/ 43 offset = (int)(0.5 + sqrt((double)(r*r - (y-r)*(y-r)))*2.0); 44 x1 = d - offset; 45 x2 = d + offset; 46 print_char(x1, x2); 47 } 48 } 49 50 Circle::~Circle(void) 51 { 52 }
Triangle.h
1 #pragma once 2 #include"Shape.h" 3 #include<cmath> 4 class Triangle:public Shape 5 { 6 public: 7 Triangle(float d,float h); 8 float getPerimeter(); 9 float getArea(); 10 char* getClassName(); 11 void Draw(); 12 ~Triangle(void); 13 private: 14 float d,h; 15 };
Triangle.cpp
1 #include "Triangle.h" 2 Triangle::Triangle(float d,float h):d(d),h(h) 3 { 4 } 5 float Triangle::getPerimeter() 6 { 7 return sqrt((d/2)*(d/2)+h*h)*2+d; 8 } 9 float Triangle::getArea() 10 { 11 return d*h/2; 12 } 13 char* Triangle::getClassName() 14 { 15 return "Triangle"; 16 } 17 void Triangle::Draw() 18 { 19 //输出另外一种由星号组成的三角形(星号居中对齐) 20 int a=(int)h;//控制组成三角形的星号的行数 21 for(int i=1;i<a+1;i++)//控制行数 22 { 23 for(int j=a-i;j>=0;j--) 24 { 25 cout<<" ";//这里是两个空格 26 } 27 for(int k=0;k<2*i-1;k++)//控制每行星号的个数。 28 { 29 if(i==0||i==a) 30 { 31 cout<<"* ";//星号后加了一个空格(为使打印出一图形更直观)。 32 } 33 else 34 if(k==0||k==2*i-2) 35 { 36 cout<<"* "; 37 } 38 39 else 40 cout<<" "; 41 } 42 cout<<endl; 43 } 44 } 45 Triangle::~Triangle(void) 46 { 47 }
Trapezoid.h
1 #pragma once 2 #include"Shape.h" 3 class Trapezoid:public Shape 4 { 5 public: 6 Trapezoid(void); 7 Trapezoid(float x1,float x2,float x3,float x4,float x5); 8 float getPerimeter(); 9 float getArea(); 10 char* getClassName(); 11 void Draw(); 12 ~Trapezoid(void); 13 private: 14 float a,b,c,d,e; 15 };
Trapezoid.cpp
1 #include "Trapezoid.h" 2 3 Trapezoid::Trapezoid(void) 4 { 5 6 } 7 Trapezoid::Trapezoid(float x1,float x2,float x3,float x4,float x5) 8 { 9 a=x1;b=x2;c=x3;d=x4;e=x5; 10 } 11 float Trapezoid::getPerimeter() 12 { 13 return a+b+c+d+e; 14 } 15 float Trapezoid::getArea() 16 { 17 return a+b; 18 } 19 char* Trapezoid::getClassName() 20 { 21 return "Trapezoid"; 22 } 23 void Trapezoid::Draw() 24 { 25 26 b=a; 27 for(c=1;c<=a;c++) 28 29 { 30 31 for(d=1;d<=a-c;d++) 32 33 printf(" "); 34 35 for(e=1;e<=b;e++) 36 37 if(c==1||c==a) printf("*"); 38 39 else if(e==1||e==b) printf("*"); 40 41 else printf(" "); 42 43 b=b+2; 44 45 printf("\n"); 46 47 } 48 } 49 50 Trapezoid::~Trapezoid(void) 51 { 52 }
Rectangle.h
1 #pragma once 2 #include"Trapezoid.h" 3 class Rectangle:public Trapezoid 4 { 5 public: 6 Rectangle(float h,float j); 7 Rectangle(void); 8 float getPerimeter(); 9 float getArea(); 10 char* getClassName(); 11 void Draw(); 12 ~Rectangle(void); 13 private: 14 float mi,mj; 15 };
Rectangle.cpp
1 #include "Rectangle.h" 2 3 4 Rectangle::Rectangle(float h,float j):mi(h),mj(j) 5 { 6 7 } 8 Rectangle::Rectangle(void) 9 { 10 11 } 12 float Rectangle::getPerimeter() 13 { 14 return (mi+mj)*2; 15 } 16 float Rectangle::getArea() 17 { 18 return mi*mj; 19 } 20 char* Rectangle::getClassName() 21 { 22 return "Rectangle"; 23 } 24 void Rectangle::Draw() 25 { 26 int mi=(int)this->mi; 27 int mj=(int)this->mj; 28 29 for(int i=0;i<mi;i++) 30 { 31 for(int j=0;j<mj;j++) 32 { 33 if(i==0||i==mi-1) 34 cout<<"*"; 35 else if(j==0||j==mj-1) 36 cout<<"*"; 37 else 38 cout<<" "; 39 } 40 cout<<endl; 41 } 42 } 43 Rectangle::~Rectangle(void) 44 { 45 }
Square.h
1 #pragma once 2 #include"Rectangle.h" 3 class Square:public Rectangle 4 { 5 public: 6 Square(float a); 7 float getPerimeter(); 8 float getArea(); 9 char* getClassName(); 10 void Draw(); 11 ~Square(void); 12 private: 13 float a; 14 };
Square.cpp
1 #include "Square.h" 2 3 4 Square::Square(float a):Rectangle(a,a) 5 { 6 this->a=a; 7 } 8 float Square::getPerimeter() 9 { 10 return 4*a; 11 } 12 float Square::getArea() 13 { 14 return a*a; 15 } 16 char* Square::getClassName() 17 { 18 return "Square"; 19 } 20 void Square::Draw() 21 { 22 //输出m行m列的空心正方矩形。 23 int m=(int)a;//m用来控制行列数。 24 for(int i=0;i<m;i++)//控制打印的行数 25 { 26 for(int j=0;j<m;j++) 27 { 28 if(i==0||i==m-1) 29 { 30 cout<<"* ";//星号后有一个空格 31 } 32 else 33 if(j==0||j==m-1) 34 { 35 cout<<"* "; 36 } 37 else 38 cout<<" "; 39 } 40 cout<<endl; 41 } 42 } 43 44 Square::~Square(void) 45 { 46 }
main.cpp
1 #include<iostream> 2 3 #include"Circle.h" 4 #include"Line.h" 5 #include"Rectangle.h" 6 #include"Shape.h" 7 #include"Trapezoid.h" 8 #include"Triangle.h" 9 #include"Square.h" 10 #include"Circle.h" 11 12 #include<vector> 13 14 using namespace std; 15 void DrawShape(const vector <Shape*> &s) 16 { 17 for(int q=0;q<=5;q++) 18 { 19 s[q]->Draw(); 20 cout<<endl<<endl; 21 } 22 } 23 24 void main() 25 { 26 vector <Shape*> vec (6); 27 28 Line lin(11); 29 vec[0] = &lin; 30 31 Trapezoid tra(6,6,8,10,12); 32 vec[1] = &tra; 33 34 Triangle tri(4,4); 35 vec[2]=&tri; 36 37 Circle cir(6); 38 vec[3]=○ 39 40 Rectangle rec(9,13); 41 vec[4]=&rec; 42 43 Square squ(7); 44 vec[5]=□ 45 46 47 DrawShape(vec); 48 49 50 51 }