




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、IC-MSP V1.0第五章第五章多态性和虚函数 手机移动设备嵌入式C+ IC-MSP V1.0q基类和派生类q单继承q多继承 q虚基类回顾IC-MSP V1.0目标q多态的概念q函数重载q运算符重载 q了解静态联编和动态联编 q虚函数 q理解抽象类的概念和用法IC-MSP V1.0程序的多态性程序的多态性 比如:C语言中的运算符”/”对于不同的数据类型具有不同的含义。 6/4=1 6.0/4=1.5 6/4.0=1.5 6.0/4.0=1.5 程序中同一符号或名字在不同情况下具有不同解释的现象称为多态性。面向对象的多态:面向对象的多态:在面向对象中,多态性是指发出同样的消息被不同类型的对象接
2、收时导致完全不同的行为多态性的基本概念IC-MSP V1.0多态的种类q 编译时多态编译时多态 是指在程序编译阶段即可确定下来的多态性,主要通过重载机制获得。包括函数重载和运算符重载。q 运行时多态运行时多态 是指必须等到程序动态运行时才可确定的多态,主要通过继承结合虚函数来完成的。普通函数使用静态绑定,而虚函数使用动态绑定。IC-MSP V1.0函数重载 C+语言中,只要在声明函数原型时形式参数的个数或者对应位置的类型不同,两个或更多的函数就可以共用同一个名字。这种在同一作用域中允许多个函数使用同一函数名的措施称为重载。函数重载的方法 int abs(int x) double abs(do
3、uble x) long abs(long x) main() abs(-5); abs(-5L); abs(3.14); 函数重载IC-MSP V1.0 1. 在一个类中说明的重载在一个类中说明的重载 在一个类中说明的重载函数之间靠所带参数个数或参数类型的不同加以区分class point int x,y; public: point()x=0;y=0; point(int x,int y) point:x=x;point:y=y; point(int i) x=y=i; ; void main() point p1; point p2(2,3); point p3(6); 函数重载方式IC
4、-MSP V1.0 2. 基类成员函数在派生类中重载基类成员函数在派生类中重载 在基类和派生类中的重载函数时,编译时根据下面两种形式区分:(1)使用“类名类名:”加以区分(2) 根据调用函数对象调用函数对象加以区分。函数重载方式IC-MSP V1.0#include class point int x,y; public: point(int x,int y) point:x=x; point:y=y; float area() return 0.0; ; class circle:public point int r; public: circle(int x,int y,int r1):p
5、oint(x,y) r=r1; float area() return 3.14*r*r; ; void main() point p1(10,10); circle c1(5,5,10); cout p1.area() n; /根据调用函数对象加以区分根据调用函数对象加以区分 cout c1.area() endl; cout c1.point:area() endl;/使用使用“类名类名:”加以区分加以区分 示例IC-MSP V1.0不要使用重载函数来描述毫无相干的函数构造函数可以重载,普通成员函数也可以重载如果两个函数的参数表相同,但是返回类型不同,则第一个声明被视为第一个的错误重复声明
6、,会被标记为编译错误 unsigned int Max( int i1, int i2 ); int Max( int , int ); / 错误:只有返回类型不同在重载函数中使用缺省函数参数时应注意调用的二义性,例如:void print(int a, int b) cout a= a ,b= b endl;void print(int a, int b, int c = 50) cout a= a ,b= b endl; 下列函数调用,由于二义性将通不过:print(10,100);函数重载应注意问题IC-MSP V1.0运算符重载IC-MSP V1.0 C+中预定义的运算符运算符的操作对
7、象只能是基本数据类型基本数据类型,如果我们要想用“+”来实现两个复数的求和运算,怎么来实现呢? 比如说:我们定义了一个复数类complex class complex public:complex(double r=0.0,double I=0.0) real=r;imag=I; void display(); private: double real; double imag; ;问题的提出IC-MSP V1.0 那么可以这样定义两个复数类的对象: complex a(10,20),b(5,8); 那么用a+b是否可以得到这两个复数的和呢? IC-MSP V1.0运算符重载的规则如下: 几乎
8、所有的运算符都可以用作重载,下列运算符不允许重载:.,*,: ,?:,# 重载之后运算符的优先级和结合性都不会改变。 运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造。一般来讲,重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型。 运算符重载概述IC-MSP V1.0运算符的重载形式有两种:重载为类的成员函数重载为类的友元函数。运算符重载为类的成员函数的语法形式如下: operator (); friend operator ();运算符重载的实现IC-MSP V1.0 q重载函数为类的成员函数的格式如下: operator (
9、)q表达式 c1 + c2 被编译程序解释为: c1.operator+(c2)q重载函数为类成员函数时,总隐含了一个参数,该参数为this指针q对双目运算符,有一个参数;对单目运算符,不再显式说明参数 运算符重载运算符重载IC-MSP V1.0#include class complex public: complex(double r=0.0,double i=0.0) real=r;imag=i; complex operator +(complex c2); complex operator -(complex c2); void display(); private: double
10、real; double imag; ;实例(续)IC-MSP V1.0complex complex:operator +(complex c2) /当使用成员函数重载运算符时,双目运算符仅有一个参数,/与一般成员函数一样,运算符函数中隐含有this指针,用于指向/调用该成员函数的对象。 return complex(real+c2.real,imag+c2.imag); /创建一个临时无名对象作为返回值 complex complex:operator (complex c2) return complex(real-c2.real,imag-c2.imag); void complex:
11、display() cout(real,imag)endl; 实例(续)IC-MSP V1.0void main() complex c1(5,4),c2(2,10),c3; cout“c1=”;c1.display(); cout“c2=”;c2.display(); c3=c1-c2; /c1.operator-(c2); cout“c3=c1-c2=”; c3.display(); c3=c1+c2; /c1.operator +(c2) cout“c3=c1+c2”; c3.display(); 实例(续)IC-MSP V1.0q重载为友元函数的定义格式如下:friend operat
12、or ()q表达式 c1 + c2 被编译程序解释为: operator+(c1,c2)q当重载友元函数时,将没有隐含的参数 this 指针q对双目运算符,友元函数有两个参数;对单目运算符,友元函数有一个参数q不能重载为友元函数的运算符是:,(), 和 - 重载为友元函数重载为友元函数IC-MSP V1.0例:复数类加减法运算重载友元函数形式#include class complex public: complex(double r=0.0,double i=0.0) real=r;imag=i;friend complex operator +(complex c1,complex c2)
13、;friend complex operator (complex c1,complex c2); 示例IC-MSP V1.0 void display(); private: double real;double imag; ; void complex:display() cout“(“real“,”imag”)”endl; complex operator +(complex c1,complex c2) return complex(c2.real+c1.real,c2.imag+c1.imag); complex operator (complex c1,complex c2) re
14、turn complex(c1.real-c2.real,c1.imag-c2.imag);IC-MSP V1.0 void main() complex c1(5,4),c2(2,10),c3; cout“c1=”;c1.display(); cout“c2=”;c2.display(); c3=c1-c2; cout“c3=c1-c2=”; c3.display(); c3=c1+c2; cout“c3=c1+c2=”; c3.display(); IC-MSP V1.0q 单目运算符最好被重载为成员函数;对双目运算符最好被重载为友元函数q 考虑一个表达式: 5.67 + c 重载为友元函
15、数时,该表达式将被解释为: operator+(complex (5.67), c) V 重载为成员函数时,该表达式将被解释为: 5.67.oprator+(c) Xq 有的双目运算符重载为成员函数为好,例如,赋值运算符两种重载形式的比较两种重载形式的比较IC-MSP V1.0#include class A public: A( )X = Y = 0; A(int i, int j)X = i; Y = j; A(A &p)X = p.X; Y = p.Y; A& operator = (A &p); int getX( )return X; int getY( )return Y; pri
16、vate: int X, Y;赋值运算符重载IC-MSP V1.0A& A:operator = (A &p) X = p.X; Y = p.Y; cout Assigment operator called.n; return *this;void main( ) A a(7, 8); A b; b = a; cout b.getX( ) , b.getY( ) endl;IC-MSP V1.0后缀运算看作双目运算符: obj+ 看作 obj+0#include class counter public: counter( )v = 0; counter operator +( );/前置
17、counter operator +( int);/ 后置 void print( ) cout v endl; private: unsigned v;重载+运算符IC-MSP V1.0counter counter : operator +( ) v+; return *this;counter counter : operator +(int) counter t; t.v = v+; return t;void main( ) counter c; for(int i = 0; i 8; i+) c+; c.print( ); for(i = 0; i 8; i+) +c; c.pri
18、nt( );IC-MSP V1.0数学函数的抽象:f(x,y) = (x+5)*y#include class F public: double operator ( ) (double x, double y) const;double F : operator ( )(double x, double y) const return (x + 5) * y; / (1.5+5)*2.2void main( )( F f; cout f( 1.5, 2.2) endl;重载()运算符IC-MSP V1.0运算符的重载实际上是函数的重载,对运算符重载的选择,遵循着函数重载的选择原则重载运算符有
19、以下各种限制:不可臆造新的运算符 不能改变运算符操作数的个数; 不能改变运算符原有的优先级; 不能改变运算符原有的结合性; 不能改变运算符原有的语法结构运算符重载的几个问题运算符重载的几个问题IC-MSP V1.0静态联编和动态联编IC-MSP V1.0联编是指一个计算机程序自身彼此关联的过程联编可以分为两种不同的联编方法:静态联编和动态联编静态联编和动态联编IC-MSP V1.0静态联编是指联编工作出现在编译连接阶段,又称为早期联编、静态束定在编译时就解决了程序中的操作调用与执行该操作代码间的关系静态联编静态联编IC-MSP V1.0include class Point public: P
20、oint(double i, double j)x=i;y=j; double Area( ) constreturn 0.0; private: double x, y;class Rectangle:public Point public: Rectangle(double i, double j, double k, double l); double Area( ) const return w*h; private: double w,h;示例IC-MSP V1.0Rectangle:Rectanagle(double i, double j, double k, double l)
21、 :Point(i,j) w = k; h = l;void fun(Point &s) cout s.Area( ) endl;void main( ) Rectangle rec(3.0, 5.2, 15.0, 25.0); fun(rec);示例(续)IC-MSP V1.0程序在编译阶段并不能确切知道将要调用的函数,只有在程序执行时才能确定将要调用的函数这种在程序运行时进行联编工作被称为动态联编,或称动态束定,又叫晚期联编静态联编和动态联编都是属于多态性的,是在不同阶段对不同实现进行不同的选择联编是对这个引用的多态性的选择,是对fun( )函数参数的多态性的选择动态联编动态联编IC-MS
22、P V1.0虚函数是动态联编的基础虚函数是非 static 的成员函数虚函数说明的方法如下: Virtual ()某类中的成员函数被说明为虚函数,意味着该成员函数在派生类中可能有不同的实现当使用这个成员函数操作指针或引用所标识对象时,该成员函数调用采取动态联编方式虚函数虚函数IC-MSP V1.0#include class Point public: Point(double i, double j)x = i; y = j; virtual double Area( ) return 0.0; private: double x,y;class Rectangle : public Poi
23、nt public: Rectangle(double i, double j ,double k, double l); virtual double Area( ) return w*h; private: double w, h;动态联编示例动态联编示例IC-MSP V1.0Rectangle:Rectanagle(double i,double j,double k,double l) : Point(i,j) w = k; h = l;void fun(Point &s) cout s.Area( ) endl;void main( ) Rectangle rec(3.0, 5.2,
24、 15.0, 25.0); fun(rec);动态联编示例(续)动态联编示例(续)IC-MSP V1.0派生类对派生类对基类虚函数基类虚函数进行替换(覆盖进行替换(覆盖)时,满足如下条件:时,满足如下条件:与基类的虚函数有相同的参数个数参数的类型与基类的虚函数的对应参数类型相同其返回值或者与基类虚函数的相同,或者都返回指针或引用,并且派生类虚函数所返回的指针或引用的类型是基类中被替换的虚函数所返回的指针或引用的基类型子类型。满足上述条件的派生类的成员函数,自然是虚函数,可以不必加 virtual 说明 说明IC-MSP V1.0分析程序,回答问题:分析程序,回答问题:#include clas
25、s A public: virtual void act1( ); void act2( ) act1( );void A:act1( ) cout A:act1( ) called. endl;示例IC-MSP V1.0class B : public A public: void act1( );void B : act1( ) cout B:act1( ) called act1( );输出结果如何?IC-MSP V1.03. 如果将如果将A:act2( )的实现改为的实现改为: void A:act2( ) A:act1( );输出结果如何?IC-MSP V1.0运行过程中的多态需要满
26、足三个条件: 1.类之间应满足赋值兼容规则。 2.要声明虚函数。 3.要由成员函数来调用或者是通过指针、引用来访问虚函数。 例:虚函数成员 #include class B0 public:virtual void display() cout“B0:display()”endl; ; IC-MSP V1.0 class B1:public B0 public:void display() cout“B1:display()”endl; ; class D1:public B1 public:void display() cout“D1:display()”display(); IC-MSP
27、V1.0 void main() B0 b0,*p; B1 b1; D1 d1; p=&b0; fun(p); p=&b1; fun(p); p=&d1; fun(p); B0(display)B1(display)D1(display)IC-MSP V1.0 注意:系统如何判断一个函数成员是不是虚函数? 1.该函数是否与基类的虚函数有相同的名称。 2.该函数是否与基类的虚函数有相同的参数 个数及相同的对应参数类型。 3.该函数是否与基类的虚函数有相同的返回 值或者满足赋值兼容性原则的指针、引用 型的返回值。 IC-MSP V1.0纯虚函数与抽象类IC-MSP V1.0 q 一般格式如下: c
28、lass virtual () = 0; ;q 在基类中不能对虚函数给出有意义的实现,把它说明为纯虚函数,它的实现留给该基类的派生类去做纯虚函数纯虚函数IC-MSP V1.0#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;使用纯虚函数使用纯虚函数IC-MSP V1.0class line : public point public: line(int i=
29、0, int j=0, int m=0, int n=0) : point(i, j) x1 = m; y1 = n; void set( )cout line:set( ) called.n; void draw( )cout line: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( )cout ellipse:set( ) called.n; void draw( )cout draw( );void setobj(point *p) p-set( );void main( ) line *lineobj = new line; ellipse *elliobj = new ellipse; drawobj(lineobj); drawobj(elliobj); cout endl; setobj(lineobj); setobj(elliobj); cout nRedraw the object
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年二级C语言试题及答案
- 家政服务培训内容
- 注会学习中的问题与解决试题及答案
- 不断更新职业技能的必要性计划
- 促进创新思维的年度活动计划
- 注册会计师考前冲刺的有效方法试题及答案
- 传统制造与现代生产计划的对比
- 如何提高秘书的决策能力计划
- 注会学习讨论组的作用试题及答案
- 图书馆与社区合作的新模式计划
- 房屋租赁合同 (三)
- 2025年北京电子科技职业学院高职单招职业适应性测试历年(2019-2024年)真题考点试卷含答案解析
- 2024年安徽宁马投资有限责任公司招聘10人笔试参考题库附带答案详解
- 《变频器原理及应用》课件
- 第16课《有为有不为》公开课一等奖创新教学设计
- 新生儿腭裂喂养护理
- 中医养生保健培训
- 2024年职业素养培训考试题库(附答案)
- 第20课 联合国与世界贸易组织-(说课稿)2023-2024学年九年级下册历史部编版(安徽)
- 《光电对抗原理与应用》课件第1章
- 网络安全题库及答案(1000题)
评论
0/150
提交评论