运算符重载ppt课件

上传人:钟*** 文档编号:5825875 上传时间:2020-02-09 格式:PPT 页数:63 大小:411KB
返回 下载 相关 举报
运算符重载ppt课件_第1页
第1页 / 共63页
运算符重载ppt课件_第2页
第2页 / 共63页
运算符重载ppt课件_第3页
第3页 / 共63页
点击查看更多>>
资源描述
第四章运算符重载 1 第四章运算符重载 4 1什么是运算符重载4 2运算符重载的方法4 3重载运算符的规则4 4运算符重载函数作为类成员函数和友元函数4 5重载双目运算符4 6重载单目运算符4 7重载流插入运算符和流提取运算符4 8类和其他数据类型的转换 2 4 1什么是运算符重载 C 为程序员提供了灵活的手段 让程序员自己定义类 自己设计相应的运算符 必须在已有的运算符基础上设计 使之应用于自己定义的类 与函数重载类似 对已有的运算符赋予新的含义 用一个运算符表示不同功能的运算 这就是运算符重载 实际上 我们在此之前已经使用了运算符重载 如 是C 的移位运算符 它又与流对象cout配合作为流插入运算符 这是C 对 进行了重载处理 3 运算符重载的实质 运算符重载是对已有的运算符赋予多重含义 必要性 C 中预定义的运算符其运算对象只能是基本数据类型 而不适用于用户自定义类型 如类 实现机制将指定的运算表达式转化为对运算符函数的调用 运算对象转化为运算符函数的实参 编译系统对重载运算符的选择 遵循函数重载的选择原则 4 例4 1通过成员函数实现复数的加法 classComplex private doublereal doubleimag public Complex real 0 imag 0 Complex doubler doublei real r imag i Complexcomplex add Complex 5 ComplexComplex complex add Complex intmain Complexc1 3 4 c2 5 10 Complexc3 c3 plex add c2 cout c1 c1 display cout c2 c2 display cout c1 c2 c3 display return0 6 在Complex类中定义了complex add函数做加法 函数的参数是引用对象 作为一个加数 在函数里定义了临时对象c 两个赋值语句相当于 c real this real c2 real c imag this imag c2 image 在main函数中通过对象c1调用加法函数 上面的语句相当于 c real c1 real c2 real c imag c1 imag c2 image 能否用 运算符实现复数加法 7 4 2运算符重载的方法 运算符重载的方法是定义一个重载运算符函数 在需要时系统自动调用该函数 完成相应的运算 运算符重载实质上是函数的重载 运算符重载函数的格式是 数据类型operator运算符 形参表 重载处理 数据类型 是重载函数值的数据类型 operator是保留字 8 规则和限制 C 中可以重载除下列运算符外的所有运算符 只能重载C 语言中已有的运算符 不可臆造新的 不改变原运算符的优先级和结合性 不能改变操作数个数 经重载的运算符 其操作数中至少应该有一个是的数据类型是类 9 两种形式 重载为类成员函数 重载为友元函数 10 运算符函数 声明形式函数类型operator运算符 形参 重载为类成员函数时 类本身是一个操作操作数 如果需要另一个操作数由函数的参数提供重载为友元函数时参数个数 原操作数个数 且至少应该有一个自定义的形参 11 不能重载的运算符只有5个 成员运算符 成员指针运算符 域运算符sizeof长度运算符 条件运算符重载函数名是由operator和运算符联合组成 复数加法运算符重载函数原型可以是 Complexoperator Complex例4 2重载运算符 用于两个复数相加 12 分析 定义一个复数类 用成员函数实现加号的重载函数 两个复数相加结果仍是复数 所以函数的返回值的类型也是复数类 用成员函数实现运算符重载函数时 调用格式是 对象名 成员名 此时对象就是一个参与运算的操作数 加法还需要另一个操作数 这个操作数用函数的参数传递 参数的类型就是复数类 而运算结果用函数值返回 13 classComplex public Complex real 0 imag 0 Complex doubler doublei real r imag i Complexoperator Complex 14 ComplexComplex operator Complex 15 intmain Complexc1 3 4 c2 5 10 c3 c3 c1 c2 cout c1 c1 display cout c2 c2 display cout c1 c2 c3 display return0 16 说明 1 用运行符重载函数取代了例4 1中的加法成员函数 从外观上看函数体和函数返回值都是相同的 2 在主函数中的表达式c3 c2 c1取代了例4 1中的c3 plex add c2 编译系统将表达式c3 c1 c2解释为c1 operator c2 对象c1调用的重载函数operator 以c2为实参计算两个复数之和 17 请考虑在例4 2中能否用一个常量和一个复数相加 如c3 3 c2 错误应该定义对象 ComplexC1 3 0 0 c3 C1 c2 注意 运算符重载后 其原来的功能仍然保留 编译系统根据运算表达式的上下文决定是否调用运算符重载函数 运算符重载和类结合起来 可以在C 中定义使用方便的新数据类型 18 4 3重载运算符的规则 1 C 只允许已有的部分运算符实施重载 2 不能重载的运算符有五个 3 重载不改变操作数的个数 4 重载不改变运算符的优先级 5 运算符重载函数不能带默认值参数 6 运算符重载函数必须与自定义类型的对象联合使用 其参数至少有一个类对象或类对象引用 7 C 默认提供 和 运算符重载 19 8 运算符重载函数可以是类成员函数也可以是类的友元函数 还可以是普通函数 9 C 规定赋值运算符 下标运算符 函数调用运算符必须定义为类的成员函数 而输出流插入 输入流提取 类型转换运算符不能定义为类的成员函数 20 4 4运算符重载函数作为类成员函数和友元函数 在例4 2程序中对运算符 进行了重载 该例将运算符重载函数定义为复数类的成员函数 从该程序中看到运算符重载为成员函数时 带一个类类型的形参 而另一个加数就是对象自己 例4 3将加法运算符重载为适用于复数加法 重载函数作为类的友元函数 21 includeclassComplex public Complex real 0 imag 0 Complex doubler real r imag 0 Complex doubler doublei real r imag i friendComplexoperator Complex 22 Complexoperator Complex 23 intmain Complexc1 3 4 c2 5 10 c3 c3 c1 c2 cout c1 c1 display cout c2 c2 display cout c1 c2 c3 display return0 24 加法运算符重载为友元函数 C 在编译时将表达式c1 c2解释为operator c1 c2 即相当于执行以下函数Complexoperator Complex 因为普通函数是不能直接访问对象的私有成员 如果普通函数必须访问对象的私有成员 可调用类的公有成员函数访问对象的私有成员 这会降低效率 25 使用成员函数重载运算符要求左操作数必须是该类对象如想将一个复数和一个整数相加 运算符重载函数作为成员函数定义如下 ComplexComplex operator int 注意在运算符 的左侧必须是Complex类对象 程序中可以写成 c3 c2 n不能写成 c3 n c2 26 如果要求在使用重载运算符时 运算符左侧操作数不是对象 就需要将运算符重载函数定义为友元函数 friendComplexoperator int 友元函数不要求第一个参数必须是类类型 但是要求实参要与形参一一对应 c3 n c2 顺序正确c3 c2 n 顺序错误 27 由于使用友元会破坏类的封装 要尽量将运算符重载函数定义为成员函数 除非有特殊需要 才使用友元函数重载运算符 28 4 5重载双目运算符 双目的意思是运算符左边和右边的操作数均参加运算 如果要重载B为类的成员函数 使之能够实现表达式oprd1Boprd2 其中oprd1为A类对象 则B应被重载为A类的成员函数 形参类型应该是oprd2所属的类型 经重载后 表达式oprd1Boprd2相当于oprd1 operatorB oprd2 29 例4 4定义一个字符串类String 用来处理不定长的字符串 重载相等 大于 小于关系运算符 用于两个字符串的等于 大于 小于的比较运算 操作数 两个操作数都是字符串类的对象 规则 两个字符串进行比较 将 运算重载为字符串类的成员函数 30 1 先建立一个String类 include includeclassString String是用户自己指定的类名 public String p NULL String char str voiddisplay private char p 31 String String char str p str voidString display cout p intmain Stringstring1 Hello string2 Book string1 display cout endl string2 display return0 32 先编写出简单的程序框架 编写和调试都比较方便 构造函数是把定义对象时的实参的地址赋予数据成员p p是指向实参的指针 程序实现了建立对象 输出字符串对象的功能 程序运行结果分别输出HelloBook 2 有了这个基础后 再增加所需的其他内容 先重载大于运算符 程序如下 33 include includeclassString public String p NULL String char str friendbooloperator String 34 voidString display cout String 35 运算符重载函数定义为友元函数 函数值是布尔类型 在函数中调用了strcmp库函数 string1 p指向 Hello string2 p指向 Book 程序运行结果是1 3 扩展到对另外三个运算符重载在String类体中声明三个重载函数是友元函数 并编写相应的函数 36 include includeclassString public String p NULL String char str friendbooloperator String 37 String String char str p str voidString display cout String 38 booloperator String 39 intmain Stringstring1 Hello string2 Book string3 Computer coutstring2 endl cout string1 string3 endl cout string1 string2 endl return0 运行结果为100 40 4 6重载单目运算符 单目运行符只要一个操作数 由于只有一个操作数 重载函数最多只有一个参数 如果将运算符重载函数定义为成员函数还可以不用参数 下面以自增运算符 为例 学习单目运算符的重载函数的编写方法 例4 5有一个Time类 数据成员有时 分 秒 要求模拟秒表 每次走一秒 满60秒进位 秒又从零开始计数 满60分进位 分又从零开始计数 输出时 分和秒的值 41 includeusingnamespacestd classTime public Time hour 0 minute 0 sec 0 Time inth intm ints hour h minute m sec s Timeoperator voiddisplay cout hour minute sec endl private inthour intminute intsec 42 TimeTime operator 前置单目运算符重载函数 sec if sec 60 sec sec 60 minute if minute 60 minute minute 60 hour hour hour 24 return this 43 43 intmain Timetime1 23 59 0 for inti 0 i 61 i time1 time1 display return0 44 C 中除了有前 外 还有后 同样的运算符由于操作数的位置不同 含义也不同 Timeoperator 形式的运算符重载 既可以对应前缀 也对应后缀 怎样区分前 和后 C 给了一个方法 在自增或自减运算符重载函数中 增加一个int形参 此时成员函数表示后缀对应的函数 例4 6在例4 5的基础上增加后 运算符重载函数 45 includeusingnamespacestd classTime public Time hour 0 minute 0 sec 0 Time inth intm ints hour h minute m sec s Timeoperator Timeoperator int voiddisplay cout hour minute sec endl private inthour intminute intsec 46 TimeTime operator 前置单目运算符重载函数 sec if sec 60 sec sec 60 minute if minute 60 minute minute 60 hour hour hour 24 return this 47 47 分析 后 运算的含义是操作数先参加其他运算后再自加 如m n 先将n的值赋予m 然后n再自加1 设计后 重载函数要遵循这个特性 TimeTime operator int Timetemp this 保存修改前的对象做返回值 this returntemp 48 intmain Timetime1 21 34 59 time2 cout time1 time1 display time1 cout time1 time1 display time2 time1 cout time1 time1 display cout time2 time2 display return0 程序运行结果如下 Time1 21 34 59 Time1 21 35 0Time1 21 35 1Time2 21 35 0 49 4 7重载流插入运算符和流提取运算符 cin和cout分别是istream类和ostream类的对象 C 已经对 和usingnamespacestd 把头文件包含到程序中 用户自定义类型的数据不能直接用 输出和输入 如想用它们进行输入或输出 程序员必须对它们重载 50 重载函数原型的格式如下 istream从格式上看 重载函数和 重载函数只能定义为友元函数 不能定义为成员函数 因为函数有两个形参 并且第一个形参不是自定义类型 51 4 7 1重载流插入运算符 例4 7在例4 2的基础上用 重载函数输出复数 分析 在类中声明 重载函数是友元函数friendostream 52 includeintmain Complexc1 2 4 c2 6 10 c3 c3 c1 c2 cout c3 return0 53 分析C 怎样处理 cout c3 运算符的左边是ostream的对象cout 右边是程序员自定义类complex的对象c3 语句符合运算符重载友元函数operator 的形参类型要求 系统调用友元函数 C 把这个语句解释为 operator cout c3 通过形参引用传递 函数中的output就是cout 函数中的c就是c3 函数就变成 cout c3 real c3 imag i endl returncout 54 returncout是将输出流现状返回 C 规定运算符 重载函数第一个参数和函数的类型必须是ostream类型的引用 目的是为了返回cout的当前值 以便连续输出 55 4 7 2重载流提取运算符 例4 8在例4 7的基础上增加流提取运算符 重载函数 用cin 输入复数 用cout istream 56 intmain Complexc1 c2 cin c1 c2 cout 重载函数中的形参input是istream类对象引用 在执行cin c1时 调用operator 函数 将cin引用传递给input input是cin的别名 同样c是c1的别名 因此 input c real c imag 相当于cin c1 real c1 imag 函数返回cin的新值 使程序可以用重载函数连续从输入流提取数据给complex类对象 57 程序逻辑上是正确的 但还有缺陷 如果输入的虚部是负数时 输出的形式变成 c2 4 10i 在负数前多个正号 可以对程序稍做修改 ostream 58 类型转换运算符的重载 类型可以当成运算符 强制类型转换 内置类型转换为类 例Common to class 类有类型转换的功能 能将其数据类型转换为本类对象 并且能够隐式进行类型转换的前提是必须提供形式一致的构造函数在内置类型作为实参时 如不和形参 类 一致 进行隐式的转换 59 59 类转换为其他数据类型Class Name operatortype return type类型的实例 类型转换函数没有参数 没有返回类型 但这个函数体内必须有一条返回语句 返回一个type类型的实例 60 60 类转换为其他类型能隐式进行 见例class to common 61 classINTEGER 转换为整数intnum public INTEGER intanint 0 num anint operatorint returnnum 61 编译器在进行类型转换时 总试图使用用户定义的类型转换函数进行类型转换 如果这样不能成功 则使用标准的类型转换机制 如果都不成功 则转换失败 在类型转换具有二义性的情况下 必须使用显式类型转换 即 type obj或type obj 将对象obj转换为具有type类型的一个对象 见例ambiguity 62 62 重载赋值运算符 对类 对象 能够使用赋值运算符 执行位拷贝的功能赋值运算符 可以被重载 用户可以定义自己需要的重载 的运算符重载函数 重载了的运算符函数operator 不能被继承 而且它必须被重载为成员函数 一般重载格式为 X X operator constX from 复制X的成员 拷贝构造函数和赋值运算符都是把一个对象的数据成员拷贝到另一对象 它们的区别是 拷贝构造函数要创建一个新对象 而赋值运算符则是改变一个已存在的对象的值 例override assigner 63 63
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 大学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!