虚函数和抽象基类的应用

/*这个实例是对一个典型例子的改写。在程序中使用虚函数和抽象基类。类的层次结构是抽象基类Shape(形状)。Point(点),Circle(圆),Cylinder(圆柱体)都是Shape类的直接派生类和间接派生类*/


//下面是一个完整的程序,为了便于阅读,分段插入了一些文字说明。

程序如下:
第(1)部分

#include <iostream>
using namespace std;
//声明抽象基类Shape
class Shape
{
public:
virtual float area( )const {return 0.0;}//虚函数
virtual float volume()const {return 0.0;}//虚函数
virtual void shapeName()const =0;//纯虚函数
};


第(2)部分
//声明Point类
class Point:public Shape//Point是Shape的公用派生类
{
public:
Point(float=0,float=0);

void setPoint(float ,float ); float getX( )const {return x;}float getY( )const {return y;}

virtual void shapeName( )const {cout<<″Point:″;}//对虚函数进行再定义

friend ostream & operator <<(ostream &,const Point &);
protected:
float x,y;
};

//定义Point类成员函数
Point::Point(float a,float b)
{x=a;y=b;}

void Point::setPoint(float a,float b)
{x=a;y=b;}

ostream & operator <<(ostream &output,const Point &p)
{     output<<″[″<<p.x<<″,″<<p.y<<″]″;
return output;
}


第(3)部分
//声明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;
return output;}



第(4)部分
//声明Cylinder类
class Cylinder:public Circle
{
public:
Cylinder (float x=0,float y=0,float r=0,float h=0);

void setHeight(float );

virtual float area( )const;

virtual float volume( )const;

virtual void shapeName( )const {cout<<″Cylinder:″;}//对虚函数进行再定义

friend ostream& operator <<(ostream&,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; return output;}


第(5)部分
//main函数
int main( )
{
Point point(3.2,4.5);//建立Point类对象point
Circle circle(2.4,1.2,5.6);
//建立Circle类对象circle
Cylinder cylinder(3.5,6.4,5.2,10.5);
//建立Cylinder类对象cylinder
point.shapeName();
//静态关联
cout<<point<<endl;
circle.shapeName();//静态关联
cout<<circle<<endl;
cylinder.shapeName();//静态关联
cout<<cylinder<<endl<<endl;
Shape *pt;//定义基类指针
pt=&point;//指针指向Point类对象
pt->shapeName( );//动态关联
cout<<″x=″<<point.getX( )<<″,y=″<<point.getY( )<<″\\narea=″<<pt->area( )
<<″\\nvolume=″<<pt->volume()<<″\\n\\n″;
pt=&circle;//指针指向Circle类对象
pt->shapeName( );//动态关联
cout<<″x=″<<circle.getX( )<<″,y=″<<circle.getY( )<<″\\narea=″<<pt->area( )
<<″\\nvolume=″<<pt->volume( )<<″\\n\\n″;
pt=&cylinder;//指针指向Cylinder类对象
pt->shapeName( );//动态关联
cout<<″x=″<<cylinder.getX( )<<″,y=″<<cylinder.getY( )<<″\\narea=″<<pt->area( )
<<″\\nvolume=″<<pt->volume( )<<″\\n\\n″;
return 0;}




程序运行结果如下。
请读者对照程序分析。
Point:[3.2,4.5](Point类对象point的数据:点的坐标)
Circle:[2.4,1.2], r=5.6 (Circle类对象circle的数据:圆心和半径)
Cylinder:[3.5,6.4], r=5.5, h=10.5 (Cylinder类对象cylinder的数据: 圆心、半径和高)
Point:x=3.2,y=4.5 (输出Point类对象point的数据:点的坐标)
area=0 (点的面积)
volume=0 (点的体积)
Circle:x=2.4,y=1.2 (输出Circle类对象circle的数据:圆心坐标)
area=98.5203 (圆的面积)
volume=0 (圆的体积)
Cylinder:x=3.5,y=6.4 (输出Cylinder类对象cylinder的数据:圆心坐标)
area=512.595 (圆的面积)
volume=891.96 (圆柱的体积)




从本例可以进一步明确以下结论:
/*(1)一个基类如果包含一个或一个以上纯虚函数,就是抽象基类。
抽象基类不能也不必要定义对象。
(2)抽象基类与普通基类不同,它一般并不是现实存在的对象的抽象(例如圆形(Circle)就是千千万万个实际的圆的抽象),它可以没有任何物理上的或其他实际意义方面的含义。
(3)在类的层次结构中,顶层或最上面的几层可以是抽象基类。
抽象基类体现了本类族中各类的共性,把各类中共有的成员函数集中在抽象基类中声明。
(4)抽象基类是本类族的公共接口。
或者说,从同一基类派生出的多个类有同一接口。
(5)区别静态关联和动态关联。
(6)如果在基类声明了虚函数,则在派生类中凡是与该函数有相同的函数名、函数类型、参数个数和类型的函数,均为虚函数(不论在派生类中是否用virtual声明)。
(7)使用虚函数提高了程序的可扩充性。
把类的声明与类的使用分离。
这对于设计类库的软件开发商来说尤为重要。
开发商设计了各种各样的类,但不向用户提供源代码,用户可以不知道类是怎样声明的,但是可以使用这些类来派生出自己的类。
利用虚函数和多态性,程序员的注意力集中在处理普遍性,而让执行环境处理特殊性。
多态性把操作的细节留给类的设计者(他们多为专业人员)去完成,而让程序人员(类的使用者)只需要做一些宏观性的工作,告诉系统做什么,而不必考虑怎么做,极大地简化了应用程序的编码工作,大大减轻了程序员的负担,也降低了学习和使用C++编程的难度,使更多的人能更快地进入C++程序设计的大门。*/


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值