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

类的说明:

一个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()<<"\narea="<<pt->area()

		<<"\nvolume="<<pt->volume()<<endl<<endl; 



	pt=&circle;				//指针指向Circle 

	pt->ShapeName();		//动态关联 

	cout<<"x="<<circle.getX()<<",y="<<circle.getY()<<"\narea="<<pt->area()

		<<"\nvolume="<<pt->volume()<<endl<<endl; 

	

	pt=&cylinder;			//指针指向cylinder 

	pt->ShapeName();		//动态关联 

	cout<<"x="<<cylinder.getX()<<",y="<<cylinder.getY()<<"\narea="<<pt->area()

		<<"\nvolume="<<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指向某一类对象后,才能确定调用的是那一个类的虚函数,故为动态关联。


 

你可能感兴趣的:(C++)