第(1)部分#include <iostream> //声明抽象基类Shapeusing namespace std; class Shape { public: virtual float area() const {return 0.0;} //虚函数 virtual float volume() const {return 0.0;} //虚函数 virtual void shapeName() const =0;}; //纯虚函数 Shape类有3个成员函数,没有数据成员。3个成员函数都声明为虚函数,其中shapeName声明为纯虚函数,因此Shape是一个抽象基类。shapeName函数的作用是输出具体的形状(如点、圆、圆柱体)的名字,这个信息是与相应的派生类密切相关的,显然这不应当在基类中定义,而应在派生类中定义。所以把它声明为纯虚函数。Shape虽然是抽象基类,但是也可以包括某些成员的定义部分。类中两个函数area(面积)和volume(体积)包括函数体,使其返回值为0(因为可以认为点的面积和体积都为0)。由于考虑到在Point类中不再对area和volume函数重新定义,因此没有把area和volume函数也声明为纯虚函数。 在Point类中继承了Shape类的area和volume函数。这3个函数在各派生类中都要用到。
第(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(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)//重载<<运算符 { utput<<"["<<p.x<<","<<p.y<<"]";return output; }
第(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(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)//重载<<运算符 { utput<<"["<<p.x<<","<<p.y<<"]";return output; }
Point从Shape继承了3个成员函数,由于“点”是没有面积和体积的,因此不必重新定义area和volume。虽然在Point类中用不到这两个函数,但是Point类仍然从Shape类继承了这两个函数,以便其派生类继承它们。shapeName函数在Shape类中是纯虚函数,在Point类中要进行定义。Point类还有自己的成员函数(setPoint,getX,getY)和数据成员(x和y)。
第(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(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; }
第(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(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; }
在Circle类中要重新定义ama函数,因为需要指定求圆面积的公式。由于圆没有体积,因此不必重新定义volume函数,而是从Point类继承volume函数。shapeName函数是虚函数,需要重新定义,赋予新的内容(如果不重新定义,就会继承Point类中的shapeName函数)。此外,Circle类还有自己新增加的成员函数(setRadius,getRadius)和数据成员(radius)。
第(4)部分//声明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&,const Cylinder&);//重载<<运算符 protected: float height; };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::getHeight() const {return height;}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; }
第(4)部分//声明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&,const Cylinder&);//重载<<运算符 protected: float height; };
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::getHeight() const {return height;}
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; }
Cylinder类是从Circle类派生的。由于圆柱体有表面积和体积,所以要对afea和volume函数重新定义。虚函数shapeName也需要重新定义。此外,Cylinder类还有自己的成员函数setHeight和数据成员radius。
第(5)部分
int main() { Point point(3.2,4.5); //建立Point类对象point Circle circle(2.4,12,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; }
int main() { Point point(3.2,4.5); //建立Point类对象point Circle circle(2.4,12,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类对象pomt的数据:点的坐标)Circle:[2.4,l.2],r=5.6 (Circle类对象circle的数据:圆心和半径)Cylinder:[3.5,6.4],r=5.5,h=lO.5 (Cylinder类对象cylinder的数据:圆心、半径和高)Point:x=3.2,y=4.5 (输出Point类对象pomt的数据:点的坐标)area=O (点的面积)volume=O (点的体积)Circle:x=2.4,y=1.2 (输出Circle类对象circle的数据:圆心坐标)area=98.5203 (圆的面积)volume=O (圆的体积)Cylinder:x=3.5,y=6.4 (输出Cylinder类对象cylinder的数据:圆心坐标)area=512.595 (圆的面积)volume=891.96 (圆柱的体积)
从本例可以进一步明确以下结论:
1、一个基类如果包含一个或一个以上纯虚函数,就是抽象基类。 2、抽象基类与普通基类不同,它可以没有任何物理上的或其他实体。 3、在类的层次结构中,顶层或最上面的几层可以是际意义方面的含义。 4、抽象基类是本类族的公共接口。或者说,从同一基类派生出的多个类有同一接口。因此能响应同一形式的消息。 5、区别静态关联和动态关联。 6、如果在基类声明了虚函数,则在派生类中凡是与该函数有相同的函数名、函数类 型、参数个数和参数类型的函数,均为虚函数(不论在派生类中是否用virtual声明)。 7、使用虚函数提高了程序的可扩充性。
#include<iostream>#include<math.h>using namespace std;class Shape //抽象基类 Shpae {public: virtual double area()=0; virtual void shapeName(){} };class Circle:public Shape //圆形 Circle{public: //Circle(); Circle(double r){radius=r;} void shapeName(){cout<<"Circle: ";} double area(){return 3.14*radius*radius;}private: double radius; };
class Rectangle:public Shape //矩形 Rectangle{public: //Rectangle(); Rectangle(double a,double b){sidea=a;sideb=b; } void shapeName(){cout<<"Rectangle: ";} double area(){return sidea*sideb;}private: double sidea; double sideb; };
class Triangle:public Shape //Triangle(三角形){public: //Triangle(); Triangle(double a,double b,double c){sidea=a;sideb=b;sidec=c;} void shapeName(){cout<<"Triangle: ";} double area() { double s=(sidea+sideb+sidec)/2; double m=s*(s-sidea)*(s-sideb)*(s-sidec); return sqrt(m); } private: double sidea; double sideb; double sidec; };int main(){ Circle C1(5.58); Rectangle R1(6.34,8.64); Triangle T2(6.54,5.13,3.89); Shape *pt[3]; pt[0]=&C1; pt[0]->shapeName(); cout << pt[0]->area()<<endl; pt[1]=&R1; pt[1]->shapeName(); cout << pt[1]->area()<<endl; pt[2]=&T2; pt[2]->shapeName(); cout << pt[2]->area()<<endl; float areaSum=0; for(int i=0;i<3;i++) {areaSum=areaSum+pt->area();} cout<<"areaSum: "<<areaSum<<endl; system("pause"); return 0; }
#include<iostream>
#include<math.h>
using namespace std;
class Base //抽象基类 Shape
{
public:
virtual double area()=0; //计算输出图形面积
virtual void shape()=0; //描述图形的名称
};
class Circle:public Base //圆形 Circle
Circle(double r){radius=r;}
void shape(){cout<<"Circle: ";}
double area(){return 3.14*radius*radius;}
private:
double radius;
class Square:public Base //正方形 square
Square(double a){sidea=a;}
void shape(){cout<<"Square: ";}
double area(){return sidea*sidea;}
double sidea;
class Rectangle:public Base //矩形 Rectangle
Rectangle(double a,double b){sidea=a;sideb=b; }
void shape(){cout<<"Rectangle: ";}
double area(){return sidea*sideb;}
double sideb;
class Trapezoid:public Base //梯形 Trapezoid
Trapezoid(double a,double b,double h){sidea=a;sideb=b;sideh=h; }
void shape(){cout<<"Trapezoid: ";}
double area(){return (sidea+sideb)*sideh/2;}
double sideh;
class Triangle:public Base //Triangle(三角形)
Triangle(double a,double b,double c){sidea=a;sideb=b;sidec=c;}
void shape(){cout<<"Triangle: ";}
double area()
double s=(sidea+sideb+sidec)/2;
double m=s*(s-sidea)*(s-sideb)*(s-sidec);
return sqrt(m);
}
double sidec;
int main()
Circle C1(8.4);
Square S1(3.18);
Rectangle R1(6.34,8.64);
Trapezoid T1(2.5,5,4);
Triangle T2(4.54,5.13,3.89);
Base *pt[5];
pt[0]=&C1;
pt[0]->shape();
cout << pt[0]->area()<<endl;
pt[1]=&S1;
pt[1]->shape();
cout << pt[1]->area()<<endl;
pt[2]=&R1;
pt[2]->shape();
cout << pt[2]->area()<<endl;
pt[3]=&T1;
pt[3]->shape();
cout << pt[3]->area()<<endl;
pt[4]=&T2;
pt[4]->shape();
cout << pt[4]->area()<<endl;
system("pause");
return 0;