版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第八课第八课 多态性多态性杜文峰杜文峰2021年年10月月17日日School of Information and Engineering, Shenzhen University2主要内容主要内容 多态性的基本概念概述 函数重载 运算符重载 多态性的基本概念多态性的基本概念概述概述 School of Information and Engineering, Shenzhen University41. 什么叫多态性(什么叫多态性(Polymorphism)?)? 在程序中同一符号或名字在不同情况下具有不同解释的现象称为多态性。 现实世界中的多态现象 变色眼镜:阳光下镜片颜色变深;室内镜片
2、颜色变浅。 猫眼瞳孔:光线充足地方瞳孔变细变窄;晚上半夜瞳孔放大、夜视能力变强。 人的皮肤对温度的反映:正常温度正常接触;遇上高温紧急避险。 C和C+中的除法运算符“/”(用户不用特别指名):当两个操作数都是整数时,执行整除功能;当两个操作数不全是整数时,执行浮点除功能。 School of Information and Engineering, Shenzhen University5面向对象程序设计中多态性的主要形式面向对象程序设计中多态性的主要形式 编译时多态 指在编译阶段即可确定下来的多态,主要通过重载机制获得。 重载机制可分为函数重载和运算符重载 函数重载:允许程序员用相同的名字定
3、义两个或更多的C+函数(包括类中的成员函数)、使得语义相近的函数可以用相同的标识符来命名。 运算符重载:允许程序员重新定义C+语言已有的运算符,以一种更自然的方式使用程序员自己定义的类类型。School of Information and Engineering, Shenzhen University6例例 “”本来只能做整数和实数相加 通过重新定义,可以使“”除了可以执行原来功能外,还可执行复数相加,矩阵相加等;只要有必要,甚至可以重新定义使“”变成减运算或除运算等。School of Information and Engineering, Shenzhen University7 运
4、行时多态 必须等到程序运行时才可确定的多态性,主要是通过继承结合动态绑定获得。 要产生运行时多态必须先设计一个类层次(继承/派生),然后在某些类中使用虚函数。 虚函数和普通函数的区别: 普通函数采用静态绑定;虚函数采用动态绑定。 (绑定实际上是代码的连接。编译时多态是静态多态(静态绑定);运行时多态是动态多态(动态绑定)。 School of Information and Engineering, Shenzhen University8引入多态性的作用引入多态性的作用 为了获得更灵活的表达方式,使程序的表示形式尽可能与所表示的内容无关。 School of Information and
5、Engineering, Shenzhen University9概念分析概念分析 重载 重定义 重命名School of Information and Engineering, Shenzhen University10 重载 在声明函数原型时,函数形式参数的个数或者对应位置的类型不同,两个或更多的函数就可以共用同一个名字。这种在同一作用域中允许多个函数使用同一个函数名的措施被称为重载(overloading); 如果在派生类中增加一个与基类成员函数同名的成员函数,但函数的形式参数、类型或次序有所不同,这时编译程序就认为是增加了一个新的成员函数,并不影响原有继承成员函数,这种情况称为函数重
6、载。 School of Information and Engineering, Shenzhen University11 重定义 如果在派生类中定义了一个函数原型与继承成员一摸一样的成员函数,则该成员函数的实现的函数体是对继承成员函数的重定义。 继承成员的重定义是在语义上重新修改继承成员函数的实现。 School of Information and Engineering, Shenzhen University12 重命名 在派生类中不改变继承成员的语义,仅仅为该成员起一个新名字。主要用它来解决名字冲突问题,以及允许派生类根据新的应用环境选择一个更合适的术语。School of In
7、formation and Engineering, Shenzhen University13函数重载函数重载 (overloading) 在声明函数原型时,形式参数个数或对应位置的类型不同,两个或更多的函数就可以共同用一个名字。这种在同一个作用域中允许多个函数使用同一个函数名的措施被称为函数重载。 函数重载的一般形式 函数名相同,但函数原型不同,特别是形式参数个数或对应位置的类型不同。 School of Information and Engineering, Shenzhen University14函数重载的例子函数重载的例子 在C语言中,求x的绝对值有两个函数: 当x是整数时用 a
8、bs(x) 当x是实数时用 fabs(x) 用户在使用时必须根据x的所属类型选择相应的函数。School of Information and Engineering, Shenzhen University15例例2 重载求绝对值函数重载求绝对值函数abs()() #include int abs(int x) return (x=0)?x:x); int abs(double x) return (x=0.0)?x:x); int abs(long x) return (x=0)?x:x); void main() coutabs(-5)”n”; /调用abs()整数版本 coutabs(
9、-5L)”n”; /调用abs()长整数版本 coutabs(3.14)”n”; /调用abs()双精度浮点版本 School of Information and Engineering, Shenzhen University16例例3 关于关于add的重载的重载 void printadd(int a,int b) /两个整数相加 couta”+”b”=”(a+b)endl; void printadd(char* a,char* b) /两字符串相接 int L1,L2;char *p,*q,*t,*k; L1=strlen(a);L2=strlen(b); p=new charL1+
10、L2+1; k=p; q=a;t=b; while(*q!=0) *p=*q;p+;q+ while(*t!=0) *p=*t;p+;t+; *p=0; couta”+”b”=”; coutkb)?a:b); char* max(char* a,char* b) /求两串中大者 char* max; max=(strcmp(a,b)0?a:b; return max; School of Information and Engineering, Shenzhen University18使用函数重载时必须注意的事项使用函数重载时必须注意的事项 不能通过函数类型(或者说函数返回值类型)来区别重载
11、函数; 不能通过typedef来定义函数重载(因为typedef只是定义类型别名,并非创建一个新的类型) 不能使用缺省参数形式来区分重载 不能通过参数不同传递方式来区分重载 School of Information and Engineering, Shenzhen University19例例include int func(int i) return i; int func(int i,int j=10;) /通过缺省参数形式来重载return (i*j); void main() coutfunc(3,4); coutfunc(5); /无法区分使用前一版本还是后一版本 School
12、of Information and Engineering, Shenzhen University20 例如 void func(int value); /无法区分 void func(int& value); 只能通过形式参数的区别来定义重载函数(通过形式参数个数或相应位置类型不同) School of Information and Engineering, Shenzhen University21编译程序对重载函数的匹配编译程序对重载函数的匹配 函数调用的实际参数与一个重载函数的形式参数完全匹配(形参个数及其相应位的类型),则选择调用该重载函数; 编译程序找不到与实际参数(个数及相
13、应位置类型)完全匹配的函数类型,但如果将一个类型隐式转换为更高级类型后能找到完全匹配的函数原型,编译程序将调用该重载函数。(注:类型转换是隐型类型转换,由C+编译程序自动完成) School of Information and Engineering, Shenzhen University22函数重载的二义性函数重载的二义性 C+编译程序无法在多个重载函数中选择正确的函数进行调用。 二义性错误是致命的,编译程序将无法生成目标代码。 二义性错误产生的主要原因为:C+语言的隐式类型转换和缺省参数School of Information and Engineering, Shenzhen Un
14、iversity23 类型隐式转换类型隐式转换 由C+编译程序自动完成。它把数值范围较小的类型转换为数值范围较大的类型。 intunsigned intlongunsigned float 例子1 设定义了函数int func(double d); 在程序中使用coutfunc(A)时没有任何问题,因为C+编译自动进行了以下类型隐式转换:charintfloatdouble 调用func(double)也没有问题。School of Information and Engineering, Shenzhen University24 例子2 以下形式无法区分,出现二义性错误了#include
15、float abs(float x)return (x=0)?x:-x); double abs(double x)return (x=0)?x:-x); void main() coutabs(3.14)/n; /调用abs(double)版本 coutabs(-5)“/n”; /出现二义性,编译无法确定采 用abs()哪个版本,因为可以有absfloat,也有absdouble School of Information and Engineering, Shenzhen University25使用缺省值参数,也会造成重载二义性使用缺省值参数,也会造成重载二义性 #include int
16、 func(int i)return i; int func(int i,int j=10)return i*j; void main() coutfunc(3,4)/n; /调用func(int,int) coutfunc(5)“/n”; /出现二义性,它不知道使用func(int)版本还是func(int,int)缺省参数版本School of Information and Engineering, Shenzhen University26函数重载的应用函数重载的应用构造函数重载构造函数重载 复习:构造函数功能和构造函数定义基本形式 功能:创建对象时自动调用它为新创建的对象进行初始化
17、基本形式:构造函数名与类名相同,不能带有函数类型 构造函数定义时形式参数主要形式 构造函数不带参数采用某个默认值作为参数; 使用普通数值作为参数采用指定值为创建的对象初始化; 以一个已知的对象作为参数用一个已知对象为新创建对象进行初始化。 School of Information and Engineering, Shenzhen University27练习练习运算符重载运算符重载 School of Information and Engineering, Shenzhen University29运算符重载运算符重载 为运算符定义新的运算功能,使它除具备有原来系统规定的功能外,还具备有
18、新定义的功能。 例如运算符“”,原来规定它能进行整数相加和实数相加功能,我们可以对它进行重载,使它具有复数相加、矩阵相加等新功能。同时也可以重载,使它完成同一个类的对象相加等。 School of Information and Engineering, Shenzhen University30运算符重载的实现运算符重载的实现 通过运算符函数来修改相应的函数功能 一般函数的定义形式: 函数类型 函数名(形式参数表)函数体 函数类型是函数返回值所属类型,函数名要符合用户自定义标识符要求,形式参数表是执行函数时所需参数的说明,函数体是函数功能描述。School of Information an
19、d Engineering, Shenzhen University31 运算符重载函数的定义形式为:函数类型 运算符重载标识 重载运算符(形参表) 函数体 运算符重载标识是专门记号 重载运算符表示重载哪一个运算符School of Information and Engineering, Shenzhen University32操作符重载定义形式操作符重载定义形式函数类型 operator 运算符(参数表)函数体 函数类型 类作用域:operator 运算符(参数表)函数体 School of Information and Engineering, Shenzhen University
20、33重载运算符函数作为类成员函数时重载运算符函数作为类成员函数时关于参数个数的讨论关于参数个数的讨论 重载一元运算符,不再显式指明参数;重载二元运算符时,只需显式指明一个参数;参数个数总是比实际参数个数少一个。 编译程序处理成员函数时,为它设置了一个this指针。在重载运算符函数中,默认this指针对应的缺省参数就是其中之一个参数,对于一元运算符函数使用的就是规定的this指针所指的参数(自身的参数),对于二元运算符对应是二元运算的左操作数。 School of Information and Engineering, Shenzhen University34例例 复数的和重载复数的和重载
21、复数类中重载“+”的函数体中: temp.real=real+other.real; temp.image=image+other.image; 相当于: temp.real=thisreal+other.real; temp.image=thisimage+other.image; 重载二元运算符时必须特别注意两个操作数的左右位置,特别是重载减法运算符: COMPLEX COMPLEX:operator -(const COMPLEX& other) COMPLEX temp; temp.real=real-other.real; /相当于thisreal-other.real temp.i
22、mage=image-other.image; /相当于thisimage-other.image return temp; School of Information and Engineering, Shenzhen University35 重载赋值运算符“=” COMPLEX COMPLEX:operator =(const COMPLEX& other) real=other.real; /相当于this.real=other.real image=other.image; /相当于this.image=other.image return *this; 声明一个对象时作初始化也采用
23、运算符“=”,但此时采用的是拷贝构造函数而不是调用重载赋值运算符。School of Information and Engineering, Shenzhen University36 重载下标运算符“ ” 下标运算符“ ”用来数某个向量的某个元素,或直接对向量中某个元素赋值,它被视为一个二元运算符。 下标运算符只能作类成员运算符进行重载,不可作为友元运算符。 School of Information and Engineering, Shenzhen University37#include #include const int MAX_SIZE=10; class VECTOR pub
24、lic: VECTOR() /构造函数 int loop;for(loop=0;loop=MAX_SIZE-1; loop=loop+1) tableloop=loop; int& operator (int index) /取向量元素 if(indexMAX_SIZE-1) cout”Index out of bounds.n”; exit(1); return tableindex; protected: int tableMAX_SIZE; /向量的内容 int main() VECTOR label; /定义向量对象 coutlabel2”n”; /输出结果为2 babel2=8; /
25、改变第三个变量的值 coutlabel2”n”; /输出结果为8 coutlabel10”n”; /引起程序异常终止,提示Index out of bounds return 0; 重载下标运算符的最大好处是提供一种向量访问的安全方法。 School of Information and Engineering, Shenzhen University38友元友元 友元:允许类的设计者选择出一组其他的类或函数,使得它们可以访问该类的私有成员和受保护成员。 C+的严格性和灵活性 严格性:强类型检查、类的私有和受保护数据访问的控制(类、封装); 灵活性:提供友元,打破类型检查的隐式和强制类型转换,
26、打破访问控制。School of Information and Engineering, Shenzhen University39 友元函数的定义形式 friend 函数类型 函数名(形式参数表); 友元运算符重载定义形式: friend 函数类型 operator 运算符(形式参数表); 不管友元函数或友元运算符重载,都必须显式地声明其所有参数,因为友元函数不是一个类的成员函数,在友元函数体中不能使用this指针。School of Information and Engineering, Shenzhen University40如重载类如重载类INTEGER成员函数重载成员函数重载“
27、+”: INTEGER operator +(INTEGER other) /重载加法运算符 INTEGER temp; temp.value=value+other.value; return temp; 此重载函数作为类成员函数,默认第一操作数是对象本身(使用了this指针),所以在使用时,第一操作数必须是对象: void main() INTEGER x(10); /创建对象x,初始化value值为10; INTERGER y=x;/创建对象y,调用拷贝构造函数初始化 INTERGER z; /创建对象z,用默认缺省值初始化 y=x+10; /合理调用,因第一操作数为对象 z=30+y;
28、 /不合法,因第一操作数不是对象 return 0; School of Information and Engineering, Shenzhen University41改用友元重载加法运算符改用友元重载加法运算符 class INTEGER friend INTEGER operator +(INTERGER obj1,INTERGER obj2); . ; INTEGER operator +(INTERGER obj1,INTERGER obj2) INTEGER temp; temp.value=obj1.value+obj2.value; return temp; void ma
29、in() INTEGER x(10); INTERGER y=x; INTERGER z; y=x+2; /合法调用,相当于y=x+INTEGER(2); z=30+y; /合法调用,相当于z=INTEGER(30)+y; School of Information and Engineering, Shenzhen University42友元函数注意点友元函数注意点 友元函数不是类的成员函数,在友元函数体中访问对象的成员,必须用对象名加运算符“.”加对象成员名。友元函数可以访问类中的所有成员(公有的、私有的、保护的),一般函数只能访问类中的公有成员; 友元函数不受类中的访问权限关键字限制,
30、可以把它放在类的公有、私有、保护部分,结果一样;School of Information and Engineering, Shenzhen University43 类的友元函数的作用域并非该类域。如果该友元函数是另一个类的成员函数,则其作用域为另一类的类域,否则与一般函数相同。 友元函数破坏了面向对象程序设计类的封装性,所以友元函数如不是必须使用,则尽可能少用。或者用其他手段保证封装性。School of Information and Engineering, Shenzhen University44 友元还有友元类概念:整个类可以是另一个类的友元。友元类的每个成员函数都是另一个类的
31、友元函数,都可访问另一个类中的保护或私有数据成员。 class A friend class B; /声明B为A的友元类 ;School of Information and Engineering, Shenzhen University45例例 赋值运算符重载为成员函数赋值运算符重载为成员函数#include class Location public: Location( )X = Y = 0; Location(int i, int j)X = i; Y = j; Location(A &p)X = p.X; Y = p.Y; Location & operator = (Locati
32、on &p); int getX( )return X; int getY( )return Y; private: int X, Y;School of Information and Engineering, Shenzhen University46Location& Location :operator = (Location &p) X = p.X; Y = p.Y; cout Assigment operator called.n; return *this;void main( ) Location a(7, 8); Location b; b = a; cout b.getX(
33、 ) , b.getY( ) endl;输出:Assignment operator called.7, 8School of Information and Engineering, Shenzhen University47例例 重载增量运算符重载增量运算符#include class counter public: counter( )v = 0; counter operator +( ); counter operator +( int); void print( ) cout v endl; private: unsigned v;counter 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.print( );School of Information and Engineering, Shenzhen University48第二个参数
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 外商投资劳动合同范本
- 地梁模板出租合同范本
- 地推人员劳务合同范本
- 墓地绿化施工合同范本
- 土地征收补偿的协议书
- 人教版四年级数学《乘法分配律》职称评审答辩说课稿
- 节能型冰箱推广创新创业项目商业计划书
- 有机薯类种植创新创业项目商业计划书
- 宠物医疗大数据分析创新创业项目商业计划书
- 农业设施隔热水槽创新创业项目商业计划书
- DBJ51T 140-2020 四川省不透水土层地下室排水卸压抗浮技术标准
- 《陆地水体及其相互关系》教学设计【高中地理(新课标)选必修1】
- 交通事故责任认定书复议申请书
- 鲁迅-资料完整版本
- 上海市二级甲等综合医院评审标准(2024版)
- 国际经济与贸易专业生涯发展展示
- 2024年天津市部分区高二年级上期中--历史(含答案)
- 浙江省稽阳联谊学校2024~2025学年高三上学期11月联考历史试题
- 脑健康中心建设指南(2024年版)
- 反诈宣讲培训课件
- 安全保卫工作方案及突发事件应急预案安全保卫应急预案
评论
0/150
提交评论