C++程序设计(谭浩强)笔记七

第八章多态性与虚函数

一、 多态性的概念

  • 向不同的对象发送同一个消息,会产生不同的行为或方法。静态多态性通过函数重载实现,动态多态性通过虚函数来实现

1.例子:

要求先建立一个Point(点)类,包含数据成员x,y(坐标点)。以它为基类,派生出一个Circle(圆)类,增加数据成员r(半径),再以Circle类为直接基类,派生出一个Cylinder(圆柱体)类,再增加数据成员h(高)。要求编写程序,重载运算符”<<“和”>>“,使之能输出以上类对象。

1.先声明Point(点)基类
#include <iostream.h>
//using namespace std;
//声明类Point
class Point
{public:
  Point(float=0,float=0);
  void setPoint(float,float);
  float getX() const {return x;}
  float getY() const {return y;}
  friend ostream & operator<<(ostream &,const Point &);
protected:
  float x,y;
};
//定义Point类的成员函数
//Point的构造函数
Point::Point(float a,float b)
{x=a;y=b;}
//设置x和y的坐标值
void Point::setPoint(float a,float b)
{x=a;y=b;}
//输出点的坐标
ostream & operator<<(ostream &output,const Point &p)
{output<<"["<<p.x<<","<<p.y<<"]"<<endl;
 return output;
}

//测试是否上述代码正确
int main()
{Point p(3.5,6.4);
 cout<<"x="<<p.getX()<<",y="<<p.getY()<<endl;
 p.setPoint(8.5,6.8);
 cout<<"p(new):"<<p<<endl;
 return 0;
}
2.在声明Point(点)的Circle(圆)派生类
class Circle:public Point
{public:
  Circle(float x=0,float y=0,float r=0);
  void setRadius(float);
  float getRadius() const;
  float area () const;
  friend ostream &operator<<(ostream &,const Circle &);
 private:
  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<<"Center=["<<c.x<<","<<c.y<<"], Radius="<<c.radius<<", area="<<c.area()<<endl;
 return output;
}
//c
int main()
{Circle c(3.5,6.4,5.2);
 cout<<"original circle:\nx="<<c.getX()<<", y="<<c.getY()<<", r="<<c.getRadius()
     <<", area="<<c.area()<<endl;
 c.setRadius(7.5);
 c.setPoint(5,5);
 cout<<"new circle:\n"<<c;
 Point &pRef=c;
 cout<<"pRef:"<<pRef;
 return 0;
}

3.在声明Circle(圆)的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;
  float area() const;
  float volume() const;
  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<<"Center=["<<cy.x<<","<<cy.y<<"], r="<<cy.radius<<", h="<<cy.height
       <<"\narea="<<cy.area()<<", volume="<<cy.volume()<<endl;
 return output;
}
//测试
int main()
{Cylinder cy1(3.5,6.4,5.2,10);
 cout<<"\noriginal cylinder:\nx="<<cy1.getX()<<", y="<<cy1.getY()<<", r="
     <<cy1.getRadius()<<", h="<<cy1.getHeight()<<"\narea="<<cy1.area()
     <<", volume="<<cy1.volume()<<endl;
 cy1.setHeight(15);
 cy1.setRadius(7.5);
 cy1.setPoint(5,5);
 cout<<"\nnew cylinder:\n"<<cy1;
 Point &pRef=cy1;
 cout<<"\npRef as a point:"<<pRef;
 Circle &cRef=cy1;
 cout<<"\ncRef as a Circle:"<<cRef;
 return 0;
}

二、多态性的实现

1.用虚函数实现多态
#include <iostream>
#include <string>
using namespace std;
class Student
 {public:
   Student(int,string,float);
   void display();
  protected:
   int num;
   string name;
   float score;
 };

Student::Student(int n,string nam,float s)
 {num=n;name=nam;score=s;}

void Student::display()
 {cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<"\n\n";}
 
class Graduate:public Student
 {public:
   Graduate(int,string,float,float);
   void display();
  private:
   float pay;
};

void Graduate::display()
 {cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<"\npay="<<pay<<endl;}

Graduate::Graduate(int n,string nam,float s,float p):Student(n,nam,s),pay(p){}

int main()
 {Student stud1(1001,"Li",87.5);
  Graduate grad1(2001,"Wang",98.5,563.5);
  Student *pt=&stud1;
  pt->display();
  pt=&grad1;
  pt->display();
  return 0;
 }
  • 输出结果是没有wage这一个内容的
  • 但是在基类Student中的void display()前加上virtual,输出结果就会有wage——因为在声明派生类display函数时会被重载为派生类中的display
2.在何种情况下用到虚函数
  • 只能将类的成员函数声明为虚函数
  • 不能定义一个与被声明为虚函数有相同的参数(数据个数及类型)和返回值相同的且同名的非virtual函数
3.纯虚函数
  • 定义:virtual 函数类型 函数名 (参数列表)=0;
  • 基类用不到,但派生类可能会用到。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Indra_ran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值