• 一个C++的多态和虚函数实例


    类的说明:


    code:

    #include<iostream>
    #include<string>
    #define PAI 3.1415926
    using namespace std;
    class Shape			//抽象类 
    {
    	public:
    		virtual float area() const //计算面积 
    		{
    			return 0.0;
    		}
    		virtual float volume() const//计算体积 
    		{
    			return 0.0;
    		}
    		virtual void ShapeName() const =0;//纯虚函数 ——形状名 
    };
    //声明点类
    class Point: public 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(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&b)
    {
    	output<<"["<<b.x<<","<<b.y<<"]"<<endl;
    	return output; 
    }
    //声明圈类
    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(float x,float y,float r):Point(x,y),radius(r){}
    void Circle::setRadius(float r)
    {
    	radius=r;
    } 
    float Circle::GetRadius()const
    {
    	return radius;
    }
    float Circle::area()const
    {
    	return PAI*radius*radius;
    }
    ostream &operator<<(ostream &output,const Circle &c)
    {
    	output<<"["<<c.x<<","<<c.y<<"],r="<<c.radius<<endl;
    	return output; 
    }
    //声明圆柱类 
    class Cylinder:public Circle
    {
    	public:
    		Cylinder(float x=0,float y=0,float r=0,float h=0);
    		void setHeight(float h);
    		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(float x,float y,float r,float h)
    	:Circle(x,y,r),height(h){}//对于多层继承,只需要给其直接基类传值 
    void Cylinder::setHeight(float h)
    {
    	height=h;
    } 
    float Cylinder::area()const
    {
    	return PAI*radius*radius;
    }
    float Cylinder::volume()const
    {
    	return PAI*radius*radius*height;
    }
    ostream &operator <<(ostream &output,const Cylinder&c)
    {
    	output<<"["<<c.x<<","<<c.y<<"],r="<<c.radius<<",h="<<c.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; 
    	
    	Shape *pt;				//定义基类指针pt
    	
    	pt=&point;				//指针指向point 
    	pt->ShapeName();		//动态关联 
    	cout<<"x="<<point.getX()<<",y="<<point.getY()<<"
    area="<<pt->area()
    		<<"
    volume="<<pt->volume()<<endl<<endl; 
    
    	pt=&circle;				//指针指向Circle 
    	pt->ShapeName();		//动态关联 
    	cout<<"x="<<circle.getX()<<",y="<<circle.getY()<<"
    area="<<pt->area()
    		<<"
    volume="<<pt->volume()<<endl<<endl; 
    	
    	pt=&cylinder;			//指针指向cylinder 
    	pt->ShapeName();		//动态关联 
    	cout<<"x="<<cylinder.getX()<<",y="<<cylinder.getY()<<"
    area="<<pt->area()
    		<<"
    volume="<<pt->volume()<<endl<<endl; 
    	cout<<endl;
    	return 0;		
    }


    Shape是图形类,它是所有图形的一个概述,抽象了图形的名称,面积,体积函数,并定义为虚函数。因为每一个图形都应该有个名字,所以声明ShapeName函数为纯虚函数,而面积和体积等特性并不一定是每一个图形都具有的特征,所以默认置零。

    Point类继承自Shape,它定义了纯虚函数ShapeName,然后添加了自己的setPoint,getX,getY成员函数,并重载了输出流运算符用于Point类的输出。

    Circle类继承自Point,它定义了纯虚函数ShapeName,以及虚函数area,然后添加了自己的setRadius,getRadius成员函数,并重载了输出流运算符用于Circle类的输出。

    Cylinder类继承自Circle,它定义了纯虚函数ShapeName,以及虚函数area,和volume,然后添加了自己的setHeight成员函数,并重载了输出流运算符用于Cylinder的输出。


    区别静态关联和动态关联:

    如果是通过对象名调用虚函数(如point.ShapeName()),在编译阶段就能确定调用的是那一个类的虚函数,所以属于静态关联。

    如果是通过基类指针调用虚函数(如pt->volume()),在编译阶段无法从语句本身确定是那一个类的虚函数,只有在运行时,pt指向某一类对象后,才能确定调用的是那一个类的虚函数,故为动态关联。


  • 相关阅读:
    Visual Studio 2008 每日提示(十一)
    Visual Studio 2008 每日提示(十二)
    13 个应该记住的最不寻常的搜索引擎
    Web1.0及WEB2.0的比较
    Comparing Properties to Methods
    1
    Struct Constructor Restrictions
    简单的动态下拉菜单
    权限设计(转)
    conceptpolymorphism
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3464793.html
Copyright © 2020-2023  润新知