/*********************************************************************************************************************************
模块说明:
虚函数和抽象基类的应用
*********************************************************************************************************************************/
#include<iostream>
using namespace std;
/*********************************************************************************************************************************
//模块说明:
声明抽象基类Shape
//模块详情:
【1】Shape类有三个成员函数,没有数据成员,三个成员函数都声明为虚函数,其中shapeName声明为纯虚函数,因此Shape是一个抽象基类.
【2】shapeName函数的具体作用是输出具体的形状。这个信息与相应的派生类密切相关的,显然这不应是在基类中定义,而应在派生类中定义。故声明为纯虚函数
【3】Shape虽然是抽象基类,但是也可以包括某些成员的定一部分,其中area()和volume()包括函数体,其返回值为0.
【4】由于考虑到在Point类中不在对area()和volume()函数重新定义,因此没有把这两个函数也声明为纯虚函数。
【5】在Point类中继承了Shape类的area()和volume()函数。
********************************************************************************************************************************/
class Shape
{
public:
virtual float area()const{return 0.0;} //虚函数
virtual float volume()const{return 0.0;} //虚函数
virtual void shapeName()const = 0; //纯虚函数
};
/******************************************************************************************************************
//模块说明
声明类Point Point是Shape的公有派生类
【1】Point从Shape继承了3个成员函数,由于“点”没有面积和体积的,因此不必重新定义area和volume,
【2】虽然在Point中用不到这两个函数,但是Point类仍然从Shape类中继承了这两个函数,以便Point类的派生类继承它们
*******************************************************************************************************************/
class Point:public Shape
{
public:
Point(float x=0,float y=0); //有默认参数的构造函数
void setPoint(float,float); //设置坐标值
float getX()const{return x;} //读X坐标,getX函数为常成员函数
float getY()const{return y;} //读Y坐标,getY函数为常成员函数
virtual void shapeName()const{cout<<"Point:";} //对虚函数进行再定义
friend ostream& operator<<(ostream&,const Point&); //友元重载运算符<<
protected:
float x,y;
};
/******************************************************************************************************************
模块说明:
下面是定义Point类的成员函数
*******************************************************************************************************************/
Point::Point(float a,float b) //Point构造函数
{
x = a;
y = b;
}
void Point:: setPoint(float a,float b) //设置x和y的坐标
{
x = a;
y = b;
}
ostream& operator<<(ostream&output,const Point&p) //重载运算符“<<”,使之能输出点的坐标
{
output<<"["<<p.x<<","<<p.y<<"]"<<endl;
return output;
}
/*******************************************************************************************************************
模块说明:
声明派生类Circle
***********************************************************************************************************************/
class Circle:public Point
{
public:
Circle(float x=0,float y=0,float r = 0); //构造函数
void setRadius(float); //设置半径
float getRadius()const; //读取半径
virtual float area()const; //计算圆的面积
virtual void shapeName()const{cout<<"Circle";}
friend ostream &operator<<(ostream&,const Circle&);
protected:
float radius;
};
/*******************************************************************************************************************
模块说明:
下面是定义Circle类的成员函数
***********************************************************************************************************************/
Circle::Circle(float a,float b,float r):Point(a,b),radius(r){} //定义构造函数
void Circle::setRadius(float r) //设置半径值
{
radius = r;
}
float Circle::getRadius()const{return radius;} //读取半径的值
float Circle::area()const{return 3.14159*radius*radius;} //计算圆面积
ostream &operator<<(ostream&output,const Circle &c)
{
output<<"["<<c.x<<","<<c.y<<"],r="<<c.radius<<endl;
return output;
}
/***********************************************************************************************************************
//模块说明:
声明Circle的派生类Cylinder
*************************************************************************************************************************/
class Cylinder:public Circle
{
public:
Cylinder(float x=0,float y=0,float r=0,float h=0); //构造函数
void setHeight(float); //设置圆柱的高
// float getHeight()const; //读取圆柱的高
virtual float area()const;
virtual float volume()const; //计算圆柱体积
virtual void shapeName()const{cout<<"Cylinder:";} //重载虚函数
friend ostream& operator<<(ostream&output,const Cylinder&); //重载运算符
protected:
float height;
};
/*******************************************************************************************************************
模块说明:
下面是定义Cylinder类的成员函数
***********************************************************************************************************************/
Cylinder::Cylinder(float a,float b,float r,float h):Circle(a,b,r),height(h){} //构造函数
void Cylinder::setHeight(float h){height=h;} //设置圆柱的高
float Cylinder:: area()const{return 2*Circle::area()+2*3.14159*radius*height;} //计算圆柱体的表面积
float Cylinder::volume()const{return Circle::area()*height;} //计算圆柱体积
ostream& operator<<(ostream&output,const Cylinder&cy) //重载运算符
{
output<<"["<<cy.x<<","<<cy.y<<"],r="<<cy.radius<<",h="<<cy.height<<endl;
return output;
}
/********************************************************************************************************************************
模块说明:
主函数
******************************************************************************************************************************** */
int main()
{
Point point(3.2,4.5);
Circle circle(2.4,1.2,5.6);
Cylinder cylinder(3.5,6.4,5.2,10.5);
point.shapeName();
cout<<point<<endl;
circle.shapeName();
cout<<circle<<endl;
cylinder.shapeName();
cout<<cylinder<<endl<<endl;
Shape *pt; //【!】【!】定义基类指针
pt = &point;
pt->shapeName();
cout<<"x="<<point.getX()<<",y="<<point.getY()<<"\narea="<<pt->area()<<"\nvolume="<<pt->volume()<<"\n\n";
pt = &circle;
pt->shapeName();
cout<<"x="<<circle.getX()<<",y="<<circle.getY()<<"\narea="<<pt->area()<<"\nvolume="<<pt->volume()<<"\n\n";
pt = &cylinder;
pt->shapeName();
cout<<"x="<<cylinder.getX()<<",y="<<cylinder.getY()<<"\narea="<<pt->area()<<"\nvolume="<<pt->volume()<<"\n\n";
system("pause");
return 0;
}