已阅读5页,还剩19页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第6章 多态性与虚函数, ,多态性的概念 虚函数 纯虚函数与抽象类,数学科学学院:汪小平 ,一、多态性的概念,观察下图,识别其中所使用的元素。,一、多态性的概念,class Node public: void Draw(Graphics,一、多态性的概念,class Shape public: void Draw(Graphics,修改后的类结构(具有抽象类)。,一、多态性的概念,考虑这些图形元素的存储方式。,Shape m_graphN;,一、多态性的概念,Shape* m_graphN; for(int i=0;iDraw(graph);,考虑下面这段程序,它的输出结果可能会是怎样的?,怎么区分指针存储的是哪一类对象地址?,Shape* m_graphN; for(int i=0;iDraw(graph); else (Staff*)m_graphi)-Draw(graph); ,一、多态性的概念,这种编程方式不简洁,程序可读性不强,可以使用C+提供的虚函数,这样使得代码非常简单。,class Shape public: virtual void Draw(Graphics,一、多态性的概念,Shape* m_graphN; for(int i=0;iDraw(graph);,程序在运行时自动识别指针所指向的对象类型,从而调用该对象重写的虚函数,实现运行时的多态性。 多态性分两种:静态多态性和动态多态性。 程序在编译时就能确定应该调用哪个函数,称为静态(或编译时的)多态性,比如:函数重载和运算符重载; 程序在运行过程中才能动态地确定操作所针对的对象,称为动态多态性。这时通过虚函数实现。,二、虚函数,虚函数是动态绑定的基础。 虚函数是非静态的成员函数,静态成员函数、内置成员函数和构造函数都不能说明为虚函数。 声明方式:在函数原型之前写virtual,但函数实现时不能再写。 具有继承性,基类中声明了虚函数,派生类中无论是否说明,同原型函数都自动为虚函数。 虚函数本质:不是重载、屏蔽,而是覆盖。 调用方式:通过基类指针或引用,执行时会 根据指针指向的对象的类类型,决定调用哪个函数。,二、虚函数,#include using namespace std; class B0 /基类B0声明 public: /外部接口 virtual void display() /虚成员函数 cout“B0:display()“endl; ; class B1: public B0 /公有派生 public: void display() cout“B1:display()“endl; ;,二、虚函数,class D1: public B1 /公有派生 public: void display() coutdisplay(); void main() /主函数 B0 b0, *p; /声明基类对象和指针 B1 b1; /声明派生类对象 D1 d1; /声明派生类对象 p= /调用类 ? 函数成员 ,二、虚函数,再谈静态关联与动态关联。,#include #include using namespace std; class Complex public: Complex(); Complex(double); Complex(double, double); operator double(); friend Complex operator +(Complex,int main() Complex c1(3,4),c2(5,-10),c3; double d; d=2.5+c1; coutdendl; c3=c1+c2; coutc3; c3=c1+2.5; coutc3; c3=2.5+c1; coutc3; c3=2.5+3.5; coutc3; return 0; ,二、虚函数,#include #include using namespace std; class Figure /定义基类figure public: void SetValue(double i, double j=0) x = i; y = j; virtual void ShowArea() cout“No area defined for this class.n“; protected: double x, y; ;,二、虚函数,class Triangle : public Figure /定义派生类triangle public: void ShowArea() /定义虚函数的不同版本 cout “Traingle has an area of “ x*0.5*y “.n“; ; class Rectangle : public Figure /定义派生类rectangle public: void ShowArea() /定义虚函数的不同版本 cout “Rectangle has an area of “ x*y “.n“; ;,二、虚函数,class Circle : public Figure /定义派生类circle public : void ShowArea() /定义虚函数的不同版本 cout “Circle has an area of “ 3.14159 * x * x“.“endl; ; int main() Figure* a4; for(int i=0;i4;i+) switch(rand()%4) case 0: ai=new Figure; break;,二、虚函数,case 1: ai=new Triangle; break; case 2: ai=new Rectangle; break; case 3: ai=new Circle; break; ai-SetValue(4,5); for(int i=0;iShowArea(); for(int i=0;i4;i+) delete ai; return 0; ,二、虚函数,特别强调: 使用虚函数实现运行时多态性的关键在于:必须通过基类指针访问这些函数。 一旦一个函数定义为虚函数,无论它传下多少层,一直保持为虚函数。 如果在派生类中没有重写虚函数,则在调用它时,使用最近基类中定义的函数版本。 一般情况下,可将各层次类中具有共性的成员函数(但表现形式不一样的函数)定义为虚函数,某个类特有的成员没有必要说明为虚函数。,二、虚函数,虚析构函数: 何时需要虚析构函数? 当你可能通过基类指针删除派生类对象时;,#include using namespace std; class Point public: Point() cout“Excuting Point destructor.“endl; ; class Circle: public Point public: Circle() cout“Excuting Circle destructor.“endl; ; int main() Point* p=new Circle; delete p; return 0; ,这种普通析构函数可能会产生什么隐患?,二、虚函数,#include using namespace std; class Point public: virtual Point() cout“Excuting Point destructor.“endl; ; class Circle: public Point public: Circle() cout“Excuting Circle destructor.“endl; ; int main() Circle* cp=new Circle; delete cp; Point* p=new Circle; delete p; return 0; ,一个好习惯:无论什么时候,都把析构函数声明为虚析构函数,特别是基类。,三、纯虚函数与抽象类,纯虚函数是定义在基类中的一种成员函数,只给出函数原型,没有任何定义。这样的函数就叫做纯虚函数。纯虚函数的存在,使得任何派生类都必须定义自己的函数版本。否则,在编译时给出错误信息。 纯虚函数定义的一般形式为:,virtual 返回值类型 函数名(形参列表) = 0;,带有纯虚函数的类称为抽象类。 抽象类不能实例出对象,但可以声明指针。,三、纯虚函数与抽象类,抽象类的作用 抽象类为抽象和设计的目的而声明,将有关的数据和行为组织在一个继承层次结构中,保证派生类具有要求的行为。 对于暂时无法实现的函数,可以声明为纯虚函数,留给派生类去实现。比如图类中的Figure的面积、体积、描绘等等。 注意 抽象类只能作为基类来使用。 不能声明抽象类的对象。 构造函数不能是虚函数,析构函数可以是虚函数。,三、纯虚函数与抽象类,#include using namespace std; class B0 /抽象基类B0声明 public: /外部接口 virtual void display( )=0; /纯虚函数成员 ; class B1: public B0 /公有派生 public: voi
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年呼伦贝尔阿荣旗市教师招聘笔试参考试题及答案解析
- 护理措施:甲亢危重病情突发处理及全面护理指导
- 2025年南京市建邺区中小学教师招聘笔试备考试题及答案解析
- 2025年郑州市上街区中小学教师招聘笔试备考试题及答案解析
- 2025年当涂县中小学教师招聘笔试参考题库及答案解析
- (新版)广东省地基与基桩承载力检测(静载荷试验)技术培训考核考试(重点)题库300题(含答案)
- 卫生院奖励与处罚
- 浙江省乐清市第二中学2026届数学高一上期末检测模拟试题含解析
- 上海市鲁迅中学2025-2026学年数学高一上期末教学质量检测试题含解析
- 上海市黄浦区格致中学2025年高一数学第一学期期末经典模拟试题含解析
- 餐饮企业日管控、周排查、月调度表格模板
- GB/T 18487.2-2001电动车辆传导充电系统电动车辆与交流/直流电源的连接要求
- GB 16670-2006柜式气体灭火装置
- GB 11032-2000交流无间隙金属氧化物避雷器
- 第1章-平面机构的结构分析和运动分析课件
- 个体户无偿使用证明范本
- 单侧唇裂手术方法比较课件
- 依伦平推广课件
- 婴幼儿配方乳粉生产企业体系检查及日常监督检查要点解析课件
- 水泵设备单机试运转记录
- 公路工程竣工验收办法实施细则
评论
0/150
提交评论