基于上篇C++ 多态:Shape类层次结构https://mp.csdn.net/mp_blog/creation/editor/133175074
【问题描述】
使用C++ 多态:Shape类层次结构中实现的Shape类层次。仅限于二维形状,如正方形,长方形、三角形和圆。和用户进行交互,让用户指定形状、位置和大小;以及绘制每个形状时所用的填充字符。用户可以指定多于一个的同样形状。当你创建每个形状时,都将指向新Shape 对象的一个Shape*指针添加到一个数组中。每个 Shape 类应用它自己的 draw 成员函数。编写一个遍历上述数组的多态的屏幕管理器,向数组中的每个对象发送draw消息,以形成屏幕图像。每次当用户指定新添的一个形状时,要重新绘制整个屏幕图像。
【具体方法】
1.创建Shape类
//Shape类
class Shape
{
public:
virtual double getArea(){}//计算面积
virtual double getVolume(){}//计算体积
virtual void print(){}//打印
virtual void draw(int x,int y,char c){}//绘制形状
Shape(){}//构造
~Shape(){}//析构
};
2.创建二维类TwoDimensionalShape,继承于Shape类
class TwoDimensionalShape : public Shape//二维
{
public:
TwoDimensionalShape(){}
virtual double getArea(){}
virtual void print(){}
virtual void draw(int x,int y,char c){}
};
3.正方形类Square,继承于二维类TwoDimensionalShape
class Square : public TwoDimensionalShape//二维的正方形
{
public:
Square(){}
Square(double side)
{
side_m=side;
}
double getArea()
{
return side_m*side_m;
}
void print()
{
cout<<"二维的正方形的面积为:"<<getArea()<<endl;
}
void draw(int x,int y,char c)
{
int a[50][50];
for(int i=0;i<50;i++)
{
for(int j=0;j<50;j++)
{
a[i][j]=0;
}
}
for(int i=0;i<50;i++)
{
for(int j=0;j<50;j++)
{
if(j>=x-1 && j<x+side_m-1 && i>=y-1 && i<y+side_m-1)
{
a[i][j]=1;
}
if(j>=x-2 && j<x+side_m && i>=y-2 && i<y+side_m && a[i][j]!=1)
{
a[i][j]=2;
}
}
}
for(int i=0;i<50;i++)
{
cout<<endl;
for(int j=0;j<50;j++)
{
if(a[i][j]==1)
cout<<c<<" ";
else
cout<<" ";
}
}
}
private:
double side_m;//边长
};
4.长方形类Rectangle,继承于二维类TwoDimensionalShape
class Rectangle_ : public TwoDimensionalShape//二维的长方形
{
public:
Rectangle_(){}
Rectangle_(double length,double width)
{
length_m=length;
width_m=width;
}
double getArea()
{
return length_m*width_m;
}
void draw(int x,int y,char c)
{
int a[50][50];
for(int i=0;i<50;i++)
{
for(int j=0;j<50;j++)
{
a[i][j]=0;
}
}
for(int i=0;i<50;i++)
{
for(int j=0;j<50;j++)
{
if(j>=x-1 && j<x+length_m-1 && i>=y-1 && i<y+width_m-1)
{
a[i][j]=1;
}
if(j>=x-2 && j<x+length_m && i>=y-2 && i<y+width_m && a[i][j]!=1)
{
a[i][j]=2;
}
}
}
for(int i=0;i<50;i++)
{
cout<<endl;
for(int j=0;j<50;j++)
{
if(a[i][j]==1)
cout<<c<<" ";
else
cout<<" ";
}
}
}
void print()
{
cout<<"二维的长方形的面积为:"<<getArea()<<endl;
}
private:
double length_m;//长
double width_m;//宽
};
5.三角形类Triangle,继承于二维类TwoDimensionalShape
class Triangle : public TwoDimensionalShape//二维的三角形 (这里定义为等腰直角三角形)
{
public:
Triangle(){}
Triangle(double side)
{
side_m=side;
}
double getArea()
{
return 0.5*side_m*side_m;
}
void draw(int x,int y,char c)
{
int a[50][50];
for(int i=0;i<50;i++)
{
for(int j=0;j<50;j++)
{
a[i][j]=0;
}
}
for(int i=0,k=-y+2;i<50;i++,k++)
{
for(int j=0;j<50;j++)
{
if(j>=x-1 && j<x+k-1 && i>=y-1 && i<y+side_m-1)
{
a[i][j]=1;
}
if(j>=x-2 && j<x+k && i>=y-3 && i<y+side_m && a[i][j]!=1)
{
a[i][j]=2;
}
}
}
for(int i=0;i<50;i++)
{
cout<<endl;
for(int j=0;j<50;j++)
{
if(a[i][j]==1)
cout<<c<<" ";
else
cout<<" ";
}
}
}
void print()
{
cout<<"二维的三角形的面积为:"<<getArea()<<endl;
}
private:
double side_m;//等腰直角三角形的边长
};
6.圆形类Circle,继承于二维类TwoDimensionalShape (在这里我想说一下,关于画圆以及如何填充圆,推荐参考文章 Bresenham 画圆算法原理)
class Circle : public TwoDimensionalShape//二维的圆形
{
public:
Circle(){}
Circle(double radius)
{
radius_m=radius;
}
double getArea()
{
return E*radius_m*radius_m;
}
void draw(int x,int y,char c)
{
//1=<r<=24
int a[50][50];
for(int i=0;i<50;i++)
{
for(int j=0;j<50;j++)
{
a[i][j]=0;
}
}
int r=x;
int p;
x=0;
y=r;
p=3-2*r;
for(;x<=y;x++)
{
a[ x+r][ y+r]=1;
a[ x+r][-y+r]=1;
a[-x+r][ y+r]=1;
a[-x+r][-y+r]=1;
a[ y+r][ x+r]=1;
a[ y+r][-x+r]=1;
a[-y+r][ x+r]=1;
a[-y+r][-x+r]=1;
if(p>=0)
{
p+=4*(x-y)+10;
y--;
}
else
{
p+=4*x+6;
}
}
for(int i=0;i<50;i++)
{
cout<<endl;
for(int j=0;j<50;j++)
{
if(a[i][j]==1)
cout<<c<<" ";
else
cout<<" ";
}
}
}
void print()
{
cout<<"二维的圆形的面积为:"<<getArea()<<endl;
}
private:
double radius_m;//圆的半径
};
7.绘制图形
char cinColor()
{
char c;
int color;
cout<<"填充字符有:1.'*' 2.'#' 3.'@' 4.'&'"<<endl;
cout<<"请输入你想绘制该形状的填充字符(编号),若超出范围则默认为'&':"<<endl;
cin>>color;
if(color==1)
c='*';
else if(color==2)
c='#';
else if(color==3)
c='@';
else
c='&';
return c;
}
8.测试程序
int main()
{
char cinColor();
vector<Shape*> shapeclass;
vector<Shape*>::iterator iter;
int a;
int x,y;
a=-1;
while(a!=0)
{
cout<<"******二维形状图形********"<<endl
<<"********1.正方形**********"<<endl
<<"********2.长方形**********"<<endl
<<"********3.三角形**********"<<endl
<<"********4.圆形************"<<endl
<<"********0.退出************"<<endl;
cout<<"请输入你所选择的形状(编号):"<<endl;
cin>>a;
switch(a)
{
case 1:
{
double side;
cout<<"Please enter the side of square:"<<endl;
cin>>side;
Shape *ptr_Square=new Square(side);
shapeclass.push_back(ptr_Square);
iter = shapeclass.begin();
(*iter)->print();
char ch=cinColor();
cout<<"请输入图形的起始坐标:"<<endl;
cin>>x>>y;
(*iter)->draw(x,y,ch);
delete ptr_Square;
}
break;
case 2:
{
double length,width;
cout<<"Please enter the length and width of the rectangle:"<<endl;
cin>>length>>width;
Shape *ptr_Rectangle_=new Rectangle_(length,width);
shapeclass.push_back(ptr_Rectangle_);
iter = shapeclass.begin();
(*iter)->print();
char ch=cinColor();
cout<<"请输入图形的起始坐标:"<<endl;
cin>>x>>y;
(*iter)->draw(x,y,ch);
delete ptr_Rectangle_;
}
break;
case 3:
{
double side;
cout<<"Please enter the side of the triangle: "<<endl;
cin>>side;
Shape *ptr_Triangle=new Triangle(side);
shapeclass.push_back(ptr_Triangle);
iter = shapeclass.begin();
(*iter)->print();
char ch=cinColor();
cout<<"请输入图形的起始坐标:"<<endl;
cin>>x>>y;
(*iter)->draw(x,y,ch);
delete ptr_Triangle;
}
break;
case 4:
{
double radius;
cout<<"Please enter the radius of Circle(0<radius<=24): "<<endl;
cin>>radius;
Shape *ptr_Circle=new Circle(radius);
shapeclass.push_back(ptr_Circle);
iter = shapeclass.begin();
(*iter)->print();
char ch=cinColor();
x=y=radius;
(*iter)->draw(x,y,ch);
delete ptr_Circle;
}
break;
case 0:
{
a=0;
}
break;
}
system("pause");
system("cls");
cout<<endl;
}
return 0;
}
完整的代码如下:
//
//习题13.14
//(使用Shape类层次结构的多态性的屏幕管理器)开发一个基本图形软件包
/
#include<iostream>
#include<vector>
#include<math.h>
#include<windows.h>
using namespace std;
#define E 3.14
//Shape类
class Shape
{
public:
virtual double getArea(){}//计算面积
virtual double getVolume(){}//计算体积
virtual void print(){}//打印
virtual void draw(int x,int y,char c){}//绘制形状
Shape(){}//构造
~Shape(){}//析构
};
class TwoDimensionalShape : public Shape//二维
{
public:
TwoDimensionalShape(){}
virtual double getArea(){}
virtual void print(){}
virtual void draw(int x,int y,char c){}
};
class Square : public TwoDimensionalShape//二维的正方形
{
public:
Square(){}
Square(double side)
{
side_m=side;
}
double getArea()
{
return side_m*side_m;
}
void print()
{
cout<<"二维的正方形的面积为:"<<getArea()<<endl;
}
void draw(int x,int y,char c)
{
int a[50][50];
for(int i=0;i<50;i++)
{
for(int j=0;j<50;j++)
{
a[i][j]=0;
}
}
for(int i=0;i<50;i++)
{
for(int j=0;j<50;j++)
{
if(j>=x-1 && j<x+side_m-1 && i>=y-1 && i<y+side_m-1)
{
a[i][j]=1;
}
if(j>=x-2 && j<x+side_m && i>=y-2 && i<y+side_m && a[i][j]!=1)
{
a[i][j]=2;
}
}
}
for(int i=0;i<50;i++)
{
cout<<endl;
for(int j=0;j<50;j++)
{
if(a[i][j]==1)
cout<<c<<" ";
else
cout<<" ";
}
}
}
private:
double side_m;//边长
};
class Rectangle_ : public TwoDimensionalShape//二维的长方形
{
public:
Rectangle_(){}
Rectangle_(double length,double width)
{
length_m=length;
width_m=width;
}
double getArea()
{
return length_m*width_m;
}
void draw(int x,int y,char c)
{
int a[50][50];
for(int i=0;i<50;i++)
{
for(int j=0;j<50;j++)
{
a[i][j]=0;
}
}
for(int i=0;i<50;i++)
{
for(int j=0;j<50;j++)
{
if(j>=x-1 && j<x+length_m-1 && i>=y-1 && i<y+width_m-1)
{
a[i][j]=1;
}
if(j>=x-2 && j<x+length_m && i>=y-2 && i<y+width_m && a[i][j]!=1)
{
a[i][j]=2;
}
}
}
for(int i=0;i<50;i++)
{
cout<<endl;
for(int j=0;j<50;j++)
{
if(a[i][j]==1)
cout<<c<<" ";
else
cout<<" ";
}
}
}
void print()
{
cout<<"二维的长方形的面积为:"<<getArea()<<endl;
}
private:
double length_m;//长
double width_m;//宽
};
class Triangle : public TwoDimensionalShape//二维的三角形 (这里定义为等腰直角三角形)
{
public:
Triangle(){}
Triangle(double side)
{
side_m=side;
}
double getArea()
{
return 0.5*side_m*side_m;
}
void draw(int x,int y,char c)
{
int a[50][50];
for(int i=0;i<50;i++)
{
for(int j=0;j<50;j++)
{
a[i][j]=0;
}
}
for(int i=0,k=-y+2;i<50;i++,k++)
{
for(int j=0;j<50;j++)
{
if(j>=x-1 && j<x+k-1 && i>=y-1 && i<y+side_m-1)
{
a[i][j]=1;
}
if(j>=x-2 && j<x+k && i>=y-3 && i<y+side_m && a[i][j]!=1)
{
a[i][j]=2;
}
}
}
for(int i=0;i<50;i++)
{
cout<<endl;
for(int j=0;j<50;j++)
{
if(a[i][j]==1)
cout<<c<<" ";
else
cout<<" ";
}
}
}
void print()
{
cout<<"二维的三角形的面积为:"<<getArea()<<endl;
}
private:
double side_m;//等腰直角三角形的边长
};
class Circle : public TwoDimensionalShape//二维的圆形
{
public:
Circle(){}
Circle(double radius)
{
radius_m=radius;
}
double getArea()
{
return E*radius_m*radius_m;
}
void draw(int x,int y,char c)
{
//1=<r<=24
int a[50][50];
for(int i=0;i<50;i++)
{
for(int j=0;j<50;j++)
{
a[i][j]=0;
}
}
int r=x;
int p;
x=0;
y=r;
p=3-2*r;
for(;x<=y;x++)
{
a[ x+r][ y+r]=1;
a[ x+r][-y+r]=1;
a[-x+r][ y+r]=1;
a[-x+r][-y+r]=1;
a[ y+r][ x+r]=1;
a[ y+r][-x+r]=1;
a[-y+r][ x+r]=1;
a[-y+r][-x+r]=1;
if(p>=0)
{
p+=4*(x-y)+10;
y--;
}
else
{
p+=4*x+6;
}
}
for(int i=0;i<50;i++)
{
cout<<endl;
for(int j=0;j<50;j++)
{
if(a[i][j]==1)
cout<<c<<" ";
else
cout<<" ";
}
}
}
void print()
{
cout<<"二维的圆形的面积为:"<<getArea()<<endl;
}
private:
double radius_m;//圆的半径
};
char cinColor()
{
char c;
int color;
cout<<"填充字符有:1.'*' 2.'#' 3.'@' 4.'&'"<<endl;
cout<<"请输入你想绘制该形状的填充字符(编号),若超出范围则默认为'&':"<<endl;
cin>>color;
if(color==1)
c='*';
else if(color==2)
c='#';
else if(color==3)
c='@';
else
c='&';
return c;
}
int main()
{
char cinColor();
vector<Shape*> shapeclass;
vector<Shape*>::iterator iter;
int a;
int x,y;
a=-1;
while(a!=0)
{
cout<<"******二维形状图形********"<<endl
<<"********1.正方形**********"<<endl
<<"********2.长方形**********"<<endl
<<"********3.三角形**********"<<endl
<<"********4.圆形************"<<endl
<<"********0.退出************"<<endl;
cout<<"请输入你所选择的形状(编号):"<<endl;
cin>>a;
switch(a)
{
case 1:
{
double side;
cout<<"Please enter the side of square:"<<endl;
cin>>side;
Shape *ptr_Square=new Square(side);
shapeclass.push_back(ptr_Square);
iter = shapeclass.begin();
(*iter)->print();
char ch=cinColor();
cout<<"请输入图形的起始坐标:"<<endl;
cin>>x>>y;
(*iter)->draw(x,y,ch);
delete ptr_Square;
}
break;
case 2:
{
double length,width;
cout<<"Please enter the length and width of the rectangle:"<<endl;
cin>>length>>width;
Shape *ptr_Rectangle_=new Rectangle_(length,width);
shapeclass.push_back(ptr_Rectangle_);
iter = shapeclass.begin();
(*iter)->print();
char ch=cinColor();
cout<<"请输入图形的起始坐标:"<<endl;
cin>>x>>y;
(*iter)->draw(x,y,ch);
delete ptr_Rectangle_;
}
break;
case 3:
{
double side;
cout<<"Please enter the side of the triangle: "<<endl;
cin>>side;
Shape *ptr_Triangle=new Triangle(side);
shapeclass.push_back(ptr_Triangle);
iter = shapeclass.begin();
(*iter)->print();
char ch=cinColor();
cout<<"请输入图形的起始坐标:"<<endl;
cin>>x>>y;
(*iter)->draw(x,y,ch);
delete ptr_Triangle;
}
break;
case 4:
{
double radius;
cout<<"Please enter the radius of Circle(0<radius<=24): "<<endl;
cin>>radius;
Shape *ptr_Circle=new Circle(radius);
shapeclass.push_back(ptr_Circle);
iter = shapeclass.begin();
(*iter)->print();
char ch=cinColor();
x=y=radius;
(*iter)->draw(x,y,ch);
delete ptr_Circle;
}
break;
case 0:
{
a=0;
}
break;
}
system("pause");
system("cls");
cout<<endl;
}
return 0;
}