第5章 多态性与虚函数.ppt
《第5章 多态性与虚函数.ppt》由会员分享,可在线阅读,更多相关《第5章 多态性与虚函数.ppt(70页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第第5章章 多态性多态性5.1 多态性概述多态性概述u所谓所谓多态性多态性就是不同对象收到就是不同对象收到相同的请求相同的请求消息消息时,产生时,产生不同的动作不同的动作。l直观地说,多态性是指用直观地说,多态性是指用一个名字定义不同的函数一个名字定义不同的函数,这些函数执行不同但又类似的操作,从而可以使用这些函数执行不同但又类似的操作,从而可以使用相同的调用方式来调用这些具有不同功能的同名函相同的调用方式来调用这些具有不同功能的同名函数。即数。即“一个接口,多种方法一个接口,多种方法”。u5.1.1 多态的分类多态的分类lC+中的多态性可以分为四类中的多态性可以分为四类:参数多态参数多态:函
2、数模板、类模板实例化产生的多态行为函数模板、类模板实例化产生的多态行为包含多态包含多态:通过虚函数实现的、定义于不同类中的同名成:通过虚函数实现的、定义于不同类中的同名成员函数的多态行为员函数的多态行为重载多态重载多态:通过函数重载和运算符重载实现通过函数重载和运算符重载实现的多态行为的多态行为强制多态强制多态:通过通过强制类型转化强制类型转化实现实现的多态行为。的多态行为。前面两种统称为前面两种统称为通用多态通用多态,而后面两种统称为,而后面两种统称为专用多态专用多态。5.1 多态性概述多态性概述u 5.1.2多态的实现多态的实现 l多多态态从从实实现现的的角角度度来来讲讲可可以以划划分分为
3、为两两类类:编编译译时的多态时的多态和和运行时的多态运行时的多态。编编译译时时的的多多态态是是通通过过静静态态联联编编来来实实现现的的。静静态态联联编编就就是是在在编编译译阶阶段段完完成成的的联联编编。编编译译时时多多态态性性主主要是要是通过函数重载和运算符重载实现通过函数重载和运算符重载实现的。的。运行时的多态运行时的多态是用是用动态联编动态联编实现的。动态联编是实现的。动态联编是运行阶段完成的联编。运行时多态性主要是运行阶段完成的联编。运行时多态性主要是通过通过虚函数来实现虚函数来实现的。的。5.2运算符重载运算符重载问题举例问题举例问题举例问题举例复数的运算复数的运算复数的运算复数的运算
4、l定义一个简化的复数类定义一个简化的复数类complex:class complex public:double real,imag;complex(double r=0,double i=0)real=r;imag=i;l若要把类若要把类complex的两个对象的两个对象com1和和com2加在一起加在一起,下面的语句是不能实下面的语句是不能实现的现的:main()complex com1(1.1,2.2),com2(3.3,4.4),total;total=com1+com2;/错误错误 /return 0;l即用即用“+”、“-”能够实现复数的加减运算,如果想实现,能够实现复数的加减运算
5、,如果想实现,必须对运算符进行重载。必须对运算符进行重载。5.2.1运算符重载概述运算符重载概述u运算符重载是对已有的运算符赋予多重含运算符重载是对已有的运算符赋予多重含义义u必要性必要性lC+中预定义的运算符其运算对象只能是基中预定义的运算符其运算对象只能是基本数据类型,而不适用于用户自定义类型(如本数据类型,而不适用于用户自定义类型(如类)类)u实现机制实现机制l将指定的运算表达式转化为对运算符函数的将指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参。调用,运算对象转化为运算符函数的实参。l编译系统对重载运算符的选择,遵循函数重编译系统对重载运算符的选择,遵循函数重
6、载的选择原则。载的选择原则。5.2.1运算符重载概述运算符重载概述规则和限制规则和限制规则和限制规则和限制u可以重载可以重载可以重载可以重载C+C+中除下列运算符外的所有运算符:中除下列运算符外的所有运算符:中除下列运算符外的所有运算符:中除下列运算符外的所有运算符:.*:?:.*:?:u只能重载只能重载只能重载只能重载C+C+语言中已有的运算符,不可臆造新的。语言中已有的运算符,不可臆造新的。语言中已有的运算符,不可臆造新的。语言中已有的运算符,不可臆造新的。u不改变原运算符的优先级和结合性。也不改变运算符不改变原运算符的优先级和结合性。也不改变运算符不改变原运算符的优先级和结合性。也不改变
7、运算符不改变原运算符的优先级和结合性。也不改变运算符的语法结构,即单目运算符只能重载为单目运算符,的语法结构,即单目运算符只能重载为单目运算符,的语法结构,即单目运算符只能重载为单目运算符,的语法结构,即单目运算符只能重载为单目运算符,双目运算符只能重载为双目运算符双目运算符只能重载为双目运算符双目运算符只能重载为双目运算符双目运算符只能重载为双目运算符u不能改变操作数个数。不能改变操作数个数。不能改变操作数个数。不能改变操作数个数。u经重载的运算符,其操作数中至少应该有一个是自定经重载的运算符,其操作数中至少应该有一个是自定经重载的运算符,其操作数中至少应该有一个是自定经重载的运算符,其操作
8、数中至少应该有一个是自定义类型。义类型。义类型。义类型。u编译程序对运算符重载的选择遵循函数重载的选择规编译程序对运算符重载的选择遵循函数重载的选择规编译程序对运算符重载的选择遵循函数重载的选择规编译程序对运算符重载的选择遵循函数重载的选择规则则则则三种形式:三种形式:u在类外定义的普通函数在类外定义的普通函数u重载为类成员函数。重载为类成员函数。u重载为友元函数。重载为友元函数。5.2.1运算符重载概述运算符重载概述5.2.2 在类外定义的运算符重载函数在类外定义的运算符重载函数u声明形式声明形式函数类型函数类型 operator 运算符(形参)运算符(形参).例:例:例:例:5.15.1#
9、includeclass complex public:double real,imag;complex(double r=0,double i=0)real=r;imag=i;/复数类定义复数类定义5.2.2 在类外定义的运算符重载函数在类外定义的运算符重载函数complex operator+(complex,co1,complex co2)complex temp(co1.real+co2.real,co1.imag+co2.imag);return temp;/运算符重载运算符重载main()complex com1(1.1,2.2),com2(3.3,4.4),total1,tota
10、l2;total2=com1+com2;total1=operator+(com1,com2);cout“real1=”total1.real“imag1=”total1.imag1endl;cout“real2=”total2.real“imag2=”total2.imag1endl return 0;/两种方法调用两种方法调用在在C+中中,可可以以把把运运算算符符重重载载函函数数定定义义成成某某个个类类的的友友元元函数函数,称为友元运算符函数。称为友元运算符函数。l1.友元运算符函数定义的语法形式友元运算符函数定义的语法形式友元运算符函数的原型在类的内部声明格式如下友元运算符函数的原型在类
11、的内部声明格式如下:class X /friend 返回类型返回类型 operator运算符运算符(形参表形参表);/在类外定义友元运算符函数的格式如下在类外定义友元运算符函数的格式如下:返回类型返回类型 operator运算符运算符(形参表形参表)函数体函数体 5.2.3友元运算符函数友元运算符函数5.2.3友元运算符函数友元运算符函数u例例用友员函数重载算术运算符用友员函数重载算术运算符#include#include iostream.hiostream.h class point class point intint x,yx,y;public:public:point(intpoin
12、t(int x1=0,int y1=0)x=x1;y=y1;x1=0,int y1=0)x=x1;y=y1;friendfriend point point operatoroperator +(const point&p1,const point&p2););friendfriend point point operatoroperator +(point&point&p)p)p.xp.x+;+;p.yp.y+;return p;+;return p;void print()void print()coutcout x y x y=()-l2.双目运算符重载双目运算符重载友元函数不是类的成员
13、函数,没有友元函数不是类的成员函数,没有友元函数不是类的成员函数,没有友元函数不是类的成员函数,没有thisthis指针。这样,用指针。这样,用指针。这样,用指针。这样,用友元函数友元函数友元函数友元函数重载双目运算符重载双目运算符重载双目运算符重载双目运算符时,时,时,时,友元函数有友元函数有友元函数有友元函数有2 2个参数个参数个参数个参数,重重重重载单目运算符载单目运算符载单目运算符载单目运算符时,要时,要时,要时,要有有有有1 1个参数个参数个参数个参数。当用友元函数重载双目运算符时当用友元函数重载双目运算符时当用友元函数重载双目运算符时当用友元函数重载双目运算符时,2,2个操作数都要
14、传递给个操作数都要传递给个操作数都要传递给个操作数都要传递给运算符函数。运算符函数。运算符函数。运算符函数。例例例例5.2.2 5.2.2 用友元运算符函数进行复数运算。用友元运算符函数进行复数运算。用友元运算符函数进行复数运算。用友元运算符函数进行复数运算。#include#include class class complexcomplex publicpublic:complex(doublecomplex(double r=0.0 r=0.0,double i=0.0);double i=0.0);5.2.3友元运算符函数友元运算符函数5.2.3友元运算符函数友元运算符函数 void
15、print();void print();/用友元运算符函数重载运算符用友元运算符函数重载运算符用友元运算符函数重载运算符用友元运算符函数重载运算符“+”+”friendfriend complexcomplex operatoroperator +(complex a(complex a,complex b);complex b);/用友元运算符函数重载运算符用友元运算符函数重载运算符用友元运算符函数重载运算符用友元运算符函数重载运算符“-”-”friendfriend complexcomplex operatoroperator -(complex a(complex a,complex
16、 b);complex b);/用友元运算符函数重载运算符用友元运算符函数重载运算符用友元运算符函数重载运算符用友元运算符函数重载运算符“*”“*”friendfriend complexcomplex operatoroperator *(complex a(complex a,complex b);complex b);/用友元运算符函数重载运算符用友元运算符函数重载运算符用友元运算符函数重载运算符用友元运算符函数重载运算符“/”/”friendfriend complexcomplex operatoroperator /(complex a(complex a,complex b);c
17、omplex b);privateprivate:double real;/double real;/复数实部复数实部复数实部复数实部 double double imagimag;/;/复数虚部复数虚部复数虚部复数虚部;5.2.3友元运算符函数友元运算符函数 complex:complex(double r,double i)/构造函数构造函数 real=r;imag=i;complex operator+(complex a,complex b)/重载运算符重载运算符“+”的实现的实现 complex temp;temp.real=a.real+b.real;temp.imag=a.ima
18、g+b.imag;return temp;complex operator-(complex a,complex b)/重载运算符重载运算符“-”的实现的实现 complex temp;temp.real=a.real-b.real;temp.imag=a.imag-b.imag;return temp;5.2.3友元运算符函数友元运算符函数complex operator*(complex a,complex b)/重载运算符重载运算符“*”的实的实现现 complex temp;temp.real=a.real*b.real-a.imag*b.imag;temp.imag=a.real*b
19、.imag+a.imag*b.real;return temp;complex operator/(complex a,complex b)/重载运算符重载运算符“/”的实的实现现 complex temp;double t;t=1/(b.real*b.real+b.imag*b.imag);temp.real=(a.real*b.real+a.imag*b.imag)*t;temp.imag=(b.real*a.imag-a.real*b.imag)*t;return temp;void complex:print()/显示输出复数显示输出复数 cout0)cout+;if(imag!=0)
20、coutimagin;5.2.3友元运算符函数友元运算符函数int main()complex A1(2.3,4.6),A2(3.6,2.8),A3,A4,A5,A6;/定义六个复数类对象定义六个复数类对象 A3=A1+A2;/复数相加复数相加 A4=A1-A2;/复数相减复数相减 A5=A1*A2;/复数相乘复数相乘 A6=A1/A2;/复数相除复数相除 A1.print();/输出复数输出复数A1 A2.print();/输出复数输出复数A2 A3.print();/输出复数相加结果输出复数相加结果A3 A4.print();/输出复数相减结果输出复数相减结果A4 A5.print();/
21、输出复数相乘结果输出复数相乘结果A5 A6.print();/输出复数相除结果输出复数相除结果A6 return 0;程序运行结果为:程序运行结果为:2.3+4.6i3.6+2.8i5.9+5.2.4i-1.3+1.8i-4.6+23i1.01731+0.486538i A3=operator+(A1,A2);A4=operator-(A1,A2);A5=operator*(A1,A2);A6=operator/(A1,A2);相相相相当当当当于于于于一般而言一般而言,如果在类如果在类X中采用中采用友元函数重友元函数重载双目运算符载双目运算符,而而aa和和bb是类是类X的两个对的两个对象象,则
22、以下两种函数调用方法是等价的则以下两种函数调用方法是等价的:aa bb;/隐式调用 operator(aa,bb);/显式调用5.2.3友元运算符函数友元运算符函数l3.单目运算符重载单目运算符重载用友元函数重载单目运算符时,需要一个显式的操作数。用友元函数重载单目运算符时,需要一个显式的操作数。例例5.2.3 用友元函数重载单目运算符用友元函数重载单目运算符“-”。#includeclass AB public:AB(int x=0,int y=0)a=x;b=y;friend AB operator-(AB obj);/声明重载单目运算符声明重载单目运算符“-”void print();p
23、rivate:int a,b;5.2.3友元运算符函数友元运算符函数5.2.3友元运算符函数友元运算符函数AB operator-(AB obj)/定义重载单目运算符定义重载单目运算符“-”obj.a=-obj.a;obj.b=-obj.b;return obj;void AB:print()couta=a b=bendl;main()AB ob1(50,60),ob2;ob1.print();ob2=-ob1;ob2.print();return 0;与与obj对象对对象对应的实参数对应的实参数对象会变吗象会变吗?程序运行的输出结果程序运行的输出结果:a=50 b=60a=-50 b=-60
24、5.2.3友元运算符函数友元运算符函数l【例例5.2.4】使用友元函数重载使用友元函数重载“+”、“-”运算符,可能运算符,可能会出现一些问题会出现一些问题#include class coord public:coord(int i=0,int j=0);void print();friend coord operator+(coord op);/声明友元运算符函数声明友元运算符函数operator+()private:/采用对象参数传递操作数采用对象参数传递操作数 int x,y;coord:coord(int i,int j)x=i;y=j;void coord:print()cout
25、x:x,y:yendl;coordcoord operator+(operator+(coordcoord op)op)对象参数对象参数的引用的引用5.2.3友元运算符函数友元运算符函数coord operator+(coord op)/友元运算符函数友元运算符函数operator+()的实现的实现 +op.x;+op.y;return op;main()coord ob(10,20);ob.print();operator+(ob);/显式调用友元运算符函数显式调用友元运算符函数 operator+()ob.print();+ob;/隐式调用友元运算符函数隐式调用友元运算符函数 operat
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第5章 多态性与虚函数 多态性 函数
限制150内