




已阅读5页,还剩45页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第8章运算符重载 目录 8 1运算符重载概述8 2单目运算符重载8 3双目运算符重载8 4比较运算符重载8 5赋值运算符重载8 6下标运算符重载8 7运算符new与delete重载 自学 8 8逗号运算符重载 自学 8 9类型转换运算符重载8 10运算符重载应用实例 问题引入 includeclasscomplex private doublereal doubleimag public complex doubler 0 0 doublei 0 0 real r imag i voiddisplay cout real image i endl voidmain intia 1 ib 2 ic ic ia ib complexa 10 20 b 5 8 c c a b C 预定义的运算符的操作对象只能是基本数据类型 那么用户自定义类型呢 运算符重载 8 1运算符重载概述 背景c 中预定义的运算符的操作对象只能是基本数据类型 而用户自定义类型 比如类 也需要有类似的运算操作能否对运算符重新定义 赋予已有符号以新的功能 运算符重载 借用 已有的运算符 对其赋予多重含义 对自定义的类对象实现自定义的新功能 同一个运算符作用于不同类型数据导致不同的行为运算符重载实质就是函数重载 运算符重载的规则 1 只能重载已有的C 运算符 不可自创新的运算符 C 中的运算符除少数几个 全部可以重载 表8 2 2 重载后运算符的优先级和结合性都不变 3 重载的功能应当与原有功能相类似运算符重载是针对新类型数据的实际需要 对原有运算符进行适当的改造 一般来讲 重载的功能应当与原有功能相类似不能改变原运算符的操作对象个数 同时至少要有一个操作对象是自定义类型 表8 2C 中可以重载的运算符 表8 1C 中可以重载的运算符 表8 2C 中不能重载的运算符 complexa 2 3 b 4 5 c c a b c add a b complexadd complexa complexb c a add b complexcomplex add complexb a b complexoperator complexa complexb complexoperator complexb 注意 运算符重载的实质就是函数重载 在实现过程中 首先把指定的表达式转化为对运算符函数的调用 运算对象转化为运算符函数的实参 然后根据实参的类型来确定需要调用的函数 这个过程在编译过程中完成的 自定义类中运算符重载的形式 2种 重载为类的公有成员函数operator 重载为类的友元函数friendoperator 二者区别 参数个数不同 成员函数方式重载 参数个数比原来运算数少一个 后缀 除外 就是缺省的this指针友元函数方式重载 参数个数与原运算数个数相同 且至少有一个参数是说明该友元的类或是该类的引用单目运算符最好重载为类的成员函数双目运算符则最好重载为类的友元函数 成员方式重载vs友元方式重载 成员方式重载 因每个成员函数总是将当前调用对象 this指针 作为该成员函数隐含的第一个参数 运算符的第一个运算对象所以若某个对象使用重载了的成员函数 自身的数据可以直接访问 就不需要再放在参数表中进行传递 少了的运算数就是该对象本身 this指针 友元方式重载 而友元函数中没有this指针 所以友元函数对某个对象的数据进行操作时 就必须通过该对象的名称来实现 因此使用到的所有运算分量都要进行传递 运算数的个数就不会有变化 一般来讲 单目运算符最好重载为成员函数 而双目运算符则最好重载为友元函数 目录 8 2单目运算符重载 includeclassSample private intn public Sample inti 0 n i voiddisplay cout n n endl voidoperator n 运算符重载 voidmain Samplea 5 a a display a operator 在C 中 单目运算符有 和 例8 1 前缀 后缀重载 运算符有前缀和后缀两种形式 和 重载运算符也有前缀和后缀两种以 重载运算符为例operator 前缀运算operator int 后缀运算使用前缀运算符 后缀运算符 例8 1 增加后缀 重载 例8 2 includeclassSample private intn public Sample inti n i voidoperator n 前缀运算符重载voidoperator int n 2 后缀运算符重载voiddisplay cout n n endl voidmain Samplea 5 b 5 a 调用后缀运算符重载 b 调用前缀运算符重载a display b display n 7n 6 includeclassSample private intn public Sample inti n i voidoperator 前缀运算符 n voidoperator int 后缀运算符 n 2 voiddisplay cout n n endl 例8 2 重载函数带返回值 例8 3 n 7n 6 重载运算符也可以具有返回值 其使用格式如同一般的成员函数一样 intoperator 前缀运算符 n returnn intoperator int 后缀运算符 n 2 returnn voidmain Samplea 5 b 5 a 调用后缀运算符重载 b 调用前缀运算符重载a display b display cout n a endl cout n b endl inti Samplec 0 i a 对 a返回值是int c a 错 C是sample类型 includeclassSample private intn public Sample inti n i Sampleoperator 前缀运算符 n returnSample n return this Sampleoperator int 后缀运算符 returnSample n voiddisplay cout n endl 改进例8 3 更改返回值为对象 voidmain Samplea 5 b 5 c 0 d 0 c a 对 C是sample 类型 a 返回值是intd b cout c c display cout a a display cout d d display cout b b display c 5a 6d 6b 6 目录 8 3双目运算符重载 双目运算符重载为类的成员函数双目运算符重载为类的友元函数 1 双目运算符重载为类的成员函数 双目运算符 运算符需要的两个运算数Boprd1Boprd2第一个运算数为类的对象本身 调用此成员函数的对象 第二个运算数通过参数传递classA operatorB oprd2 Aa b aBb a operatorB b 例 a b a operator b includeclassVector 向量 x y private intx y public Vector x 0 y 0 Vector intx1 inty1 x x1 y y1 voiddisplay coutx v x tmp y y v y returntmp 返回tmp对象 VectorVector operator Vectorv Vectortmp 定义一个tmp对象tmp x x v x tmp y y v y returntmp 返回tmp对象 例8 4 voidmain Vectorv1 6 8 v2 3 6 v3 v4 cout v1 v1 display cout v2 v2 display v3 v1 v2 v3 v1 operator v2 cout v1 v2 v3 display v4 v1 v2 v4 v1 operator v2 cout v1 v2 v4 display 2 双目运算符重载为类的友元函数 例8 5 运算符所需的运算数都要通过函数的形参表来传递 参数表中形参从左到右的顺序就是运算符运算数的顺序 includeclassVector private intx y public Vector x 0 y 0 Vector intx1 inty1 x x1 y y1 voiddisplay cout x y endl friendVectoroperator Vectorv1 Vectorv2 friendVectoroperator Vectorv1 Vectorv2 Vectoroperator Vectorv1 Vectorv2 Vectortmp tmp x v1 x v2 x tmp y v1 y v2 y returntmp 目录 8 4比较运算符重载 比较运算符 如 的运算符重载 任意给3个Line类的对象 都可以判断是否有两个相加大于第3个 includeclassLine intlen public Line intn len n Lineoperator Linel 运算符重载 intx len l len returnLine x 无名临时对象 booloperator Linel 运算符重载 return len l len true false Linetemp x returntemp voidmain Linea 10 b 5 c 14 if a b c main 中定义三个对象a b和c 表达式 a b c 运算过程为 a operator b operator c 目录 8 5赋值运算符重载 在C 中有两种类型的赋值运算符 直接赋值的运算符 等 先计算后赋值的复合赋值运算符 8 5 1运算符 的重载 赋值运算符 的原有含义是将赋值号右边表达式的结果拷贝给赋值号左边的变量 为了保证同类对象之间能够进行赋值操作 每个类应定义赋值操作 重载运算符 如果程序中没有定义赋值操作 则c 编译器自动生成 实现将赋值号右边对象的数据成员依次拷贝到赋值号左边对象的数据成员中 浅拷贝 浅拷贝带来的悬挂指针问题 classM private int p public M inti M voidprint M M inti p newint i M M deletep 编译器自动生成 M M constM 自己定义 深拷贝 M M constM 例8 8 include includeclasssample public sample char pn p newchar strlen pn 1 strcpy p pn sample constsample sample sample constsample s voidmain sampleinst1 firstobject sampleinst2 secondobject cout 执行语句之前 endl cout inst1 p inst1 disp cout inst2 p inst2 disp cout 执行语句之后 endl inst2 inst1 cout inst1 p inst1 disp cout inst2 p inst2 disp inst3 inst2 inst1 目录 略 8 5 2运算符 和 的重载 对于标准数据类型 和 的作用是将一个数据与另一个数据进行加法或减法运算后再将结果回送给赋值号左边的变量中 a ba a b 对 例8 7 进行修改 includeclassVector private intx y public Vector x 0 y 0 Vector intx1 inty1 x x1 y y1 voiddisplay cout x y endl Vectoroperator Vectorv friendVector 修改书上 Vector voidmain Vectorv1 6 8 v2 3 6 v3 v4 cout v1 v1 display cout v2 v2 display v3 v1 v2 v3 operator v1 v2 cout v1 v2后 v1 v1 display v4 v1 v2 v4 v1 operator v2 cout v1 v2后 v1 v1 display 目录 8 6下标运算符重载 下标运算符 通常用于取数组的某个元素下标运算符重载可实现数组下标越界检测等 只能作为类的成员函数 不能作为类的友元函数 例8 9 include includeclasswords private intlen char str public words char s str newchar strlen s 1 strcpy str s len strlen s words delete s voiddisp cout str endl charoperator intn charwords operator intn const if n len 1 cout 数组下标超界 return 0 返回一个特殊字符 elsereturn str n voidmain wordsword ThisisC Book word disp cout 位置0 cout word 0 endl 显示 T cout 位置15 cout word 15 endl 显示 K cout 位置25 cout word 25 endl 显示 超界 目录 略 8 7运算符new与delete重载 自学 C 提供new与delete运算符用于内存管理 大多数情况下 它们是非常有效的 但有些情况下我们需要自己管理内存 以克服new与delete的不足 这就要重载运算符new与delete 使其按照要求完成对内存的管理 例8 10 include includeclassRect public Rect intl intw length l width w voiddisp cout 面积 length width endl void operatornew size tsize voidoperatordelete void p private intlength width void Rect operatornew size tsize cout 重载new运算符分配内存 endl returnmalloc size voidRect operatordelete void p free p cout 重载delete运算符释放内存 endl voidmain Rect p p newRect 5 9 p disp deletep 程序的main 函数中使用的new和delete运算符都调用相应的重载运算符成员函数 分别用于内存的分配和释放 目录 略 8 8逗号运算符重载 自学 逗号运算符是双目运算符 和其他运算符一样 我们也可以通过重载逗号运算符来完成期望完成的工作 逗号运算符构成的表达式为 左运算数 右运算数 该表达式返回右运算数的值 如果用类的成员函数来重载逗号运算符 则只带一个右运算数 而左运算数由指针this提供 例8 11 给出以下程序的执行结果 include includeclassPoint public Point x 0 y 0 Point intx1 inty1 x x1 y y1 voiddisp cout x y endl Pointoperator Pointr Pointoperator Pointr private intx y PointPoint operator Pointr Pointtemp temp x x r x temp y y r y returntemp PointPoint operator Pointr Pointtemp temp x r x temp y r y returntemp voidmain Pointr1 3 3 r2 5 8 r3 2 4 r1 disp r2 disp r3 disp r1 r1 r2 r3 r3 r1 disp 计算r1 r1 r2 r3 r3 先计算 r1 r2 r3 返回r2 r3的结果 将其与r3进行逗号运算 返回r3的结果 目录 8 9类型转换运算符重载 C 中提供了标准类型的相互转换intn int 1 87 则n 1 类型转换运算符重载 格式如下 operator 注 与以前的重载运算符函数不同的是 类型转换运算符重载函数没有返回类型 因为类型名就代表了它的返回类型 没有任何参数 在调用过程中要带一个对象实参 例8 12 Length类将用户输入的meter 以米为单位 值转换成以千米为单位的长度 includeclassLength private intmeter public Length intm meter m operatorfloat return 1 0 meter 1000 voidmain Lengtha 1500 floatm float a 带一个对象实参进行调用cout m m 千米 endl m 1 5千米 例8 13 include includeclassStrings public Strings strcpy str Strings charst strcpy str st voiddisp cout str endl operatorchar returnstr private charstr SIZE staticconstintSIZE 80 voidmain Stringsps1 Sunrise sunset ps1 disp char ps2 ps2 char ps1 调用 char 运算符重载函数cout ps2 endl 实际上 类型转换运算符将对象转换成类型名规定的类型 转换时的形式就像强制转换一样 如果没有转换运算符定义 直接用强制转换是不行的 因为强制转换只能对标准数据类型进行操作 对类类型的操作是没有定义的 转换运算符重载的缺点是无法定义其类对象运算符操作的真正含义 因为只能进行相应对象成员数据和一般数据变量的转换操作 目录 例8 14 运算符重载应用实例 矩阵的基本运算 加 减 乘法运算 设计一个矩阵类 数据成员 用一维数组模拟矩阵 存储矩阵中的数据 int elems 用两个整型数据成员表示矩阵的行列数 shortrows cols include includeclassmatrix private shortrows cols int elems public matrix matrix shortr shortc matrix intoperator shortrow shortcol voiddisp voidsetelem shortrow shortcol intval friendmatrixoperator matrixp matrixq friendmatrixoperator matrixp matrixq friendmatrixoperator matrixp matrixq matrix matrix elems NU
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 绿色建筑配置方案设计意图
- 建筑方案设计评标办法
- 小建筑竞赛排版方案设计
- 建筑规划方案设计怎么写
- 石碣洁净室施工方案
- 钢结构工程水电施工方案
- 教育科技企业2025年在线辅导产品迭代规划报告
- 教育直播平台课程内容创新与用户满意度研究报告2025
- 矿业防洪设计方案
- 2025年河南省新郑市事业单位招聘考试公共基础知识试题题库及答案
- 电信人工智能学习考试题(附答案)
- 肝门部胆管癌诊断和治疗指南(2025版)解读课件
- 急诊危重症患者转运专家共识解读课件
- 律所销售培训
- 《发芽小麦粉气流分级产品及其面筋蛋白品质的研究》
- 2025年危险化学品经营单位主要负责人安全生产全国考试题库(含答案)
- 青岛版五四制科学五年级上册科学学生活动手册参考答案
- 社区街道网格员安全培训
- 村卫生室医疗废物管理制度
- GB/T 44698-2024电动踝关节
- 生理学基础题库(46道)
评论
0/150
提交评论