C程序设计多态性及虚函数.ppt_第1页
C程序设计多态性及虚函数.ppt_第2页
C程序设计多态性及虚函数.ppt_第3页
C程序设计多态性及虚函数.ppt_第4页
C程序设计多态性及虚函数.ppt_第5页
免费预览已结束,剩余25页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第10章 多太性和虚函数,本章内容提要,函数重载 运算符重载 静态联编和动态联编 虚函数 纯虚函数和抽象类 虚析构函数,面向对象的三大特征: 封装性(基础) 继承性(关键) 多态性(补充) C+语言多态性表现: 静态联编 函数重载 运算符重载 动态联编 虚函数,多态性和虚函数,一、 函数重载,是多态性的一种体现 如,汽车都有方向盘,加运算等 函数重载就是赋给同一个函数名多个含义。 重载函数的意义在于可以用相同的函数名访问一组相互关联的函数。 成员函数重载,例10.1:,问题:定义一个string类,对其中的构造函数进行重载。,#include #include class string pub

2、lic: string(char *s);/构造函数 string(string ,string:string(char *s) length=strlen(s); sp=new charlength+1; strcpy(sp,s); string:string(string ,void main() string str1(This is a demo.); str1.print(); coutstr1.getlen()endl; char *s1=That is a program.; string str2(s1); string str3(str2); str3.print(); co

3、utstr3.getlen()endl; ,程序运行结果为: This is a demo. 15 That is a program. 18,使用重载函数注意:,不要使用重载函数描述不相干的函数 在类中,构造函数和普通成员函数均可以重载 避免与函数的默认参数产生二义性,二、运算符重载,运算符重载(operate overloading)就是赋予已有的运算符多重含义。 运算符重载实质是函数重载,运算符重载的选择与函数重载类似,会根据运算符的操作数的类型、个数和顺序来进行运算符函数的选择。,使用运算符重载注意:,几乎所有的运算符都可用作重载。除了以下运算符:.* : ?:。 运算符重载的不变性

4、优先级不变和结合性不变 操作数个数不变和语法语义不变 运算符重载遵循的原则 重载运算符的含义清楚,并且有实际意义 重载运算符不能有二义性,运算符重载函数的两种形式,C+中每个运算符对应着一个运算符函数。 int a=1,b=2;a+b; 表达式a+b在编译时,将被解释为函数调用形式:operator+(a,b)。其中,operator是一个关键字,它与后面的+共同组成了该运算符函数的函数名。,形式一:运算符函数重载为类的成员函数 格式: 类型 X:operator (参数表) 类型:该运算符函数的返回值类型 X:需要重载该运算符的类名 operator:定义运算符重载函数的关键字 :需要被重载

5、的运算符与operator共同组成该运算符函数的函数名。,运算符重载函数的两种形式,例:,问题:定义一个复数,并重载加法+、-运算符以满足对复数运算的要求。,#include class complex public: complex()real=imag=0; complex(double r,double i) real=r;imag=i; friend complex operator +(const complex ,complex operator +(const complex ,void main() complex c1(2.0,3.0),c2(4.0,-2.0),c3; c3

6、=c1+c2; coutnc1+c2=; print(c3); c3=c1-c2; coutnc1-c2=; print(c3); ,程序运行结果为: c1+c2=6+1i c1-c2=-2+5i,形式二:运算符函数重载为类的友元函数 可以定义一个与某一个运算符函数同名的全局函数,然后再将该全局函数声明为类的友元函数,从而实现运算符的重载 格式: friend 类型 operator (形参表); 注意:有些运算符不能重载为友元,如=、()、 、-,运算符重载函数的两种形式,例:,问题:用友元函数代替成员函数,重新编写上例。,#include class complex public: com

7、plex()real=imag=0; complex(double r,double i) real=r;imag=i; complex operator +(const complex ,inline complex complex:operator +(const complex ,void main() complex c1(2.0,3.0),c2(4.0,-2.0),c3; c3=c1+c2; coutnc1+c2=; print(c3); c3=c1-c2; coutnc1-c2=; print(c3); ,程序运行结果为: c1+c2=6+1i c1-c2=-2+5i,其他运算符重

8、载举例,扩展分数运算符 例10.2 重载取负运算符“-”。 例10.3 重载加法运算符“+”。 例10.4 重载自加运算符“+”。 例10.5 重载类型转换符“long”。 例10.7 重载下标运算符“”。 只能被重载为类的非静态成员函数。 下标运算符只有一个参数,表示下标值。 注意:一般说来,单目运算符最好被重载为成员函数,双目运算符最好被重载为友元函数。,三、静态联编和动态联编,联编是计算机程序彼此关联的过程。即,将被调用的函数连接编译到调用它的程序中。 联编有两种: 静态联编:在编译阶段进行联编的,又称早期联编。 动态联编:在运行阶段进行联编的,又称晚期联编。 一般多数都是静态联编,只有

9、满足一定条件时才会实现动态联编。,1.静态联编,在编译时就解决了程序中的操作调用与执行该操作代码间的关系,确定这种关系又被称为束定,在编译时束定又称静态束定。,例10.8:,问题:静态联编的例子。,#include class Point public: Point(double i,double j)x=i;y=j; double Area() constreturn 0.0; private: double x,y; ;,class circle:public Point public: circle(double i,double j,double k); double Area() c

10、onstreturn 3.14*r*r; private: double r; ; circle:circle(double i,double j,double k):Point(i,j) r=k; ,void fun(Point ,程序运行结果为: 0,2.动态联编,动态联编和静态联编也都属于多态性。它们是在不同阶段对不同实现进行不同的选择。如上例。 动态联编是在虚函数的支持下实现的。 动态联编的实现是有条件的: 公有继承是基础; 虚函数是关键; 对象指针或引用作为引导。,四、虚函数,虚函数是动态联编的基础。虚函数是成员函数,而且是非static的成员函数。 虚函数的定义方法: class

11、类名 virtual 类型 函数名(参数表); ; 注意:动态联编通过对象指针和引用操作虚函数,如果使用对象来操作函数,则使用静态联编。,例10.9:,问题:动态联编的例子。,#include class Point public: Point(double i,double j)x=i;y=j; virtual double Area() constreturn 0.0; private: double x,y; ;,class circle:public Point public: circle(double i,double j,double k); virtual double Are

12、a() constreturn 3.14*r*r; private: double r; ; circle:circle(double i,double j,double k):Point(i,j) r=k; ,void fun(Point ,程序运行结果为: 706.5,例10.10:,问题:指针指向虚函数的例子。,#include class A public: virtual void f()coutA:f() called.n; ; class B:public A public: virtual void f() coutB:f() calledn; ;,void main() B

13、b; A /动态联编,束定到B:f() ,程序运行结果为: B:f() called,虚函数在使用时应注意:,类的成员函数声明为虚函数,意味着该成员函数在派生类中可能有不同的实现。 虚函数可以在一个或多个派生类中被重新定义,但要求函数名、返回值类型和参数类型、顺序等要相同。 只有类的成员函数才能声明为虚函数。 基类的指针可以指向该基类的不同派生类对象,但具体是否使用动态联编,还要看所调用 的是否是虚函数。,五、纯虚函数和抽象类,在基类中只给出说明,而在派生类中给出定义的虚函数称纯虚函数,包含纯虚函数的类叫抽象类。,1.纯虚函数,纯虚函数在基类中的一般说明格式: class 类名 virtual

14、 类型 函数名(参数表)=0; ; 说明:声明了纯虚函数的基类只是用于继承,仅作为一个接口,具体功能在派生类中实现。,例10.11:,问题:纯虚函数的例子。,#include class point public: point(int i=0,int j=0)x0=i;y0=j; virtual void set()=0;/纯虚函数 virtual void draw()=0;/纯虚函数 protected: int x0,y0; ;,class line:public point public: line(int i=0,int j=0,int m=0,int n=0):point(i,j)

15、 x1=m;y1=n; /虚函数 void set()coutline:set() called.n; /虚函数 void draw()coutline:draw() called.n; protected: int x1,y1; ;,class ellipse:public point public: ellipse(int i=0,int j=0,int p=0,int q=0):point(i,j) x2=p;y2=q; /虚函数 void set()coutellipse:set()called.n; /虚函数 void draw()coutellipse:draw() called.

16、n; protected: int x2,y2;,void drawobj(point *p) p-draw(); void setobj(point *p) p-set(); ,void main() line *lineobj=new line; ellipse *elliobj=new ellipse; drawobj(lineobj);drawobj(elliobj); coutendl; setobj(lineobj);setobj(elliobj); coutnredraw the object .n; drawobj(lineobj); drawobj(elliobj);,程序运

17、行结果为: line:draw() called. ellipse:draw() called. line:set() called. ellipse:set() called. redraw the object . line:draw() called. ellipse:draw() called.,2.抽象类,含有纯虚函数,那么这个类就被称为抽象类。 抽象类必须用做派生其它类的基类,而不能直接创建对象实例。但可以使用抽象类的指针。,例10.12:,问题:编写一个用于计算各类形状的总面积。,#include class shape public: virtual float area()=

18、0;/纯虚函数 ;,/三角形 class triangle:public shape protected: float H,W; public: triangle(float h,float w)H=h;W=w; float area()return H*W*0.5;/纯虚函数重用 ;,/长方形 class rectangle:public triangle public: rectangle(float h,float w):triangle(h,w) float area()return H*W;/纯虚函数重用 ;,/圆面积 class circle:public shape protected: float radius; public: circle(float r)radius=r; float area()return radius*radius*3.14;/纯虚函数重用 ;,/求总面积 float total(shape *s,int n) float sum=0; for(int i=0;iarea(); return sum; ,void main() shape *s4;/基类型数组指针 s0=new triangle(3.0,4.0); s1=new rectangle(2.0,4.0); s2=new circle(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论