第十二章多态性与虚函数
1. 在例1
2.1程序基础上作一些修改。定义Point(点)类,由Point类派生出Circle(圆)类,再由Circle类
派生出Cylinder(圆柱体)类。将类的定义部分分别作为3个头文件,对它们的成员函数的声明部分分别作为
3个源文件(.cpp文件),在主函数中用#include命令把它们包含进来,形成一个完整的程序,并上机运行。
//Point.h
using namespace std;
class Point
{
public:
Point(float=0,float=0);
void set_point(float,float);
float get_x() const;
float get_y() const;
friend ostream& operator <<(ostream&,const Point&);
virtual float area() const;
virtual float volum() const;
virtual ~Point();
protected:
float x;
float y;
};
//Circle.h
#include "Point.h"
using namespace std;
class Circle: public Point
{
public:
Circle(float=0,float=0,float=0);
void set_radius(float);
float get_radius() const;
virtual float area() const;
// virtual float volum() const; //volum继承Point的就可以了
friend ostream& operator <<(ostream&,const Circle&);
~Circle();
protected:
float radius;
};
//Cylinder.h
#include "Circle.h"
using namespace std;
class Cylinder: public Circle
public:
Cylinder(float=0,float=0,float=0,float=0);
void set_height(float h);
float get_height() const;
virtual float area() const;
virtual float volum() const;
friend ostream& operator <<(ostream&,const Cylinder&); ~Cylinder();
protected:
float height;
};
//Point.cpp
135
第十二章多态性与虚函数
#include
#include "Point.h"
using namespace std;
Point::Point(float a,float b):x(a),y(b){}
void Point::set_point(float a,float b)
{
x=a;
y=b;
}
float Point::get_x() const
{
return x;
}
float Point::get_y() const
{
return y;
}
ostream& operator <<(ostream& output,const Point& p) {
output<<"("<
return output;
}
float Point::area() const
{
return 0;
}
float Point::volum() const
{
return 0;
Point::~Point(){}
//Circle.cpp
#include
#include "Circle.h"
using namespace std;
Circle::Circle(float a,float b,float r):Point(a,b),radius(r){}
void Circle::set_radius(float r)
{
radius=r;
}
float Circle::get_radius() const
{
return radius;
}
float Circle::area() const
{
return 3.1415926*radius*radius;
}
ostream& operator <<(ostream& output,const Circle& c)
{
output<<"("< output<<"Radius: "< return output; } Circle::~Circle(){} //Cylinder.cpp #include #include "Cylinder.h" using namespace std; 136 第十二章多态性与虚函数 Cylinder::Cylinder(float a,float b,float r,float h):Circle(a,b,r),height(h){} void Cylinder::set_height(float h) { height=h; } float Cylinder::get_height() const { return height; } float Cylinder::area() const { return 2*Circle::area()+2*3.1415926*radius*height; float Cylinder::volum() const { return Circle::area()*height; } ostream& operator <<(ostream& output,const Cylinder& c) { output<<"("< output<<"Radius: "< output<<"Height: "< return output; } Cylinder::~Cylinder(){} //main.cpp #include #include "Cylinder.h" using namespace std; 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); cout< cout< cout< return 0; } /* 运行结果 * (3.2,4.5) * (2.4,1.2) * Radius: 5.6 * (3.5,6.4) * Radius: 5.2 * Height: 10.5 */ 2. 请比较函数重载和虚函数。在概念和使用方式方面有什么区别? 略。 3. 在例12.3的基础上作以下修改,并作出必要的讨论。 1. 把构造函数修改为带参数的函数,在建立对象时初始化。 将circle的构造函数写为: Circle(int r=0):radius(r){}//必须有默认构造函数 137 第十二章多态性与虚函数 2. 先不将函数声明为virtual,在main函数中另设一个指向Circle类对象的指变量,使之 指向Circle。运行程 序,分析结果。 先执行Circle(派生类)构造函数,再执行Point(基类)构造函数。 3. 不作第2点的修改而将析构函数声明为virtual,运行程序,分析结果。 与上小问一致。 4. 写一个程序,定义抽象基类Shape,由它派生出3个派生类:Circle(圆类)、Rectangle (矩形)、 Triangle(三角形),用一个函数printArea分别输出以上三者的面积,3个图形的数据在定义对象时给定。 #include #include #include using namespace std; class Shape { public: virtual void shapName() const=0; virtual void printArea() const{} virtual ~Shape(){} }; class Circle: public Shape { public: Circle(double r=0):radius(r){} virtual void shapName() const { cout<<"Circle: "< } virtual void printArea() const { cout<<"Area = "<<3.1415926*radius*radius< } private: double radius; }; class Rectangle: public Shape { public: Rectangle(double l,double h):length(l),height(h){} virtual void shapName() const { cout<<"Rectangle: "< } virtual void printArea() const cout<<"Area = "< } private: double length; double height; }; class Triangle: public Shape { public: Triangle(double x,double y,double z):a(x),b(y),c(z){} virtual void shapName() const { 138 第十二章多态性与虚函数 cout<<"Triangle: "< } virtual void printArea() const { double s=(a+b+c)/2; double area=sqrt(s*(s-a)*(s-b)*(s-c)); cout<<"Area = "< } private: double a; double b; double c; }; int main() { Shape *p; Circle cir(5.5); Rectangle rec(2.8,3.3); Triangle tri(1.2,3.8,3.0); p=○ p->shapName(); p->printArea(); p=&rec; p->shapName(); p->printArea(); p=&tri; p->shapName(); p->printArea(); return 0; /* 运行结果 * Circle: * Area = 95.0332 * Rectangle: * Area = 9.24 * Triangle: * Area = 1.49666 */ 5. 写一个程序,定义抽象基类Shape,由它派生出5个派生类:Circle(圆形)、Square(正方形)、 Rectangle(矩形)、Trapezoid(梯形)、Trigangle(三角形)。用虚函数分别计算几种图形面积,并求它们 的和。要求用基类指针数组,使它的每一个元素指向一个派生类对象。 #include #include #include using namespace std; class Shape { public: virtual void shapName() const=0; virtual void printArea() const{} virtual ~Shape(){} virtual float area() const{return 0;} }; 139 第十二章多态性与虚函数 class Circle: public Shape { public: Circle(double r=0):radius(r){} virtual void shapName() const { cout<<"Circle: "< } virtual void printArea() const { cout<<"Area = "<<3.1415926*radius*radius< } virtual float area() const{return 3.1415926*radius*radius;} private: double radius; }; class Rectangle: public Shape { public: Rectangle(double l=0,double h=0):length(l),height(h){} virtual void shapName() const { cout<<"Rectangle: "< } virtual void printArea() const { cout<<"Area = "< } virtual float area() const{return length*height;} private: double length; double height; }; class Square: public Shape { public: Square(double l=0):length(l){} virtual void shapName() const { cout<<"Square: "< } virtual void printArea() const { cout<<"Area = "< } virtual float area() const{return length*length;} private: double length; }; class Trapezoid: public Shape { public: Trapezoid(double upper=0,double lower=0,double h=0): upper_parallel(upper),lower_parallel(lower),height(h){} virtual void shapName() const { cout<<"Trapezoid: "< } virtual void printArea() const 140