C 面向对象程序设计.ppt_第1页
C 面向对象程序设计.ppt_第2页
C 面向对象程序设计.ppt_第3页
C 面向对象程序设计.ppt_第4页
C 面向对象程序设计.ppt_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1 C 面向对象程序设计 第十章运算符重载与类模板 2 学习目标 理解为什么要进行运算符重载 在什么情况下要进行运算符重载 掌握通过成员函数重载运算符 借助友元函数实现运算符重载 理解引用在运算符重载中的作用 引用作为参数和返回值的好处和用法 理解类型转换的必要性 能够在程序设计中正确应用类型转换 理解为什么要引入类模板的概念 掌握类模板的应用 3 10 1为什么要进行运算符重载 10 1 1运算符重载的例子在程序中 经常会使用运算符 但C 中已经定义的运算符都是针对基本数据类型的 那么能否将它们用于复杂的类对象呢 在学习本章之前 我们往往是编写实现相应运算功能的函数来解决复杂类型的运算问题 首先来看一个复数加法运算的例子 请注意程序中 加法运算时表达式的书写形式 例6 1 复数的加运算 见教材P133 4 程序说明 在 例10 1 为了解决复数的存储问题 在复数类Complex中 定义了两个私有成员变量 real 复数的实部 和imag 复数的虚部 并定义了公有的复数加法函数add 和友元输出函数print 显示复数 在main函数中定义了三个复数对象 使用加法函数add进行3个复数的相加 并输出结果 在程序中三个复数相加的表达式为 c4 c1 add c2 add c3 用这种方式书写表达式 不仅形式复杂 不符合人们的日常书写习惯 而且不易理解 复数的运算越复杂 书写的表达式越困难 给使用自定义类编写程序带来诸多不便 如果能够像使用基本类型那样用运算符来书写复数运算表达式 如c4 c1 c2 c3 不仅书写简单 也更容易理解 这正是在C 中引入了运算符重载的意义所在 下面通过使用运算符重载进行复数加运算例子来了解如何进行运算符的重载 5 例10 2 使用运算符重载进行复数加运算 见教材P134输出结果 11 2i程序说明 该程序的作用和 例10 1 相同 只是用运算符重载函数代替了加法函数 比较两个程序不难发现 例10 2 中书写的复数相加表达式 含义清晰 便于书写 让复数类的使用变得更加简易 程序中 运算符重载的定义如下 Complexoperator Complex它与一般函数的定义非常相似 不同的是运算符重载函数的名字 operator 是由 operator 关键字和紧随其后的运算符 组成 关键字 operator 表明该函数是一个运算符重载函数 在 例10 2 中 该函数是作为类Complex的成员函数 因此把以这种方式的运算符重载称作重载为类运算符 6 例10 3 重载为友元运算符进行复数加运算 见教材P136输出结果 11 2i程序说明 本例实现的功能与 例10 1 和 例10 2 完全相同 本例中 运算符重载函数的定义如下 Complexoperator Complex由于该函数是一般的普通函数 不是类的成员函数 只是为能够访问类的私有数据成员 而把其声明为类的友元函数 因此在定义时参数表中必须指定两个参数 第1个参数作为运算符的左操作数 第2参数作为运算符的右操作数 7 10 1 2注意事项 C 对运算符重载作出了一定的限制和规定 在重载运算符时 需要注意以下几点 不是所有运算符都可以被重载 C 的大部分运算符都可以被重载 可以重载的运算符如下 newnew deletedelete 其中 运算符 是函数调用运算符 是下标运算符 和 的一元 二元形式都可以被重载 自增运算符 和自减运算符 的前置 后置形式都可以被重载 以上可重载运算符中 除了赋值运算符 之外 基类中所有被重载的运算符都将被派生类继承 8 不可以重载的运算符如下 成员运算符 成员对象选择符 解析运算符 条件运算符 重载不能改变运算符的优先级 假定已定义了复数类Complex 并且已定义了加法和乘法运算符重载函数 Complexc1 1 2 c2 3 4 c3 5 6 answer answer c1 c2 c3 在这个表达式中 乘法运算优先级高于加法运算 它等效于answer c1 c2 c3 如同系统定义数据类型一样 可以使用括号强制改变重载运算符的计算顺序 例如 answer c1 c2 c3 重载不能改变运算符的结合律 9 重载不能改变运算符的操作数个数 重载的一元运算符仍然是一元运算符 重载的二元运算符仍然是二元运算符 C 中唯一的三元运算符 不能被重载 运算符 和 既可以用作一元运算符和二元运算符 对这几个运算符 要分别把他们重载为一元运算符和二元运算符 不能创建新的运算符 只有现用的运算符才能被重载 运算符重载函数的参数至少有一个必须是类的对象或者是类的对象的引用 运算符只能被显式重载 不存在隐式重载 例如 运算符 和 已被分别重载 这不意味着运算符 或 已被重载 运算符重载函数不能带有缺省参数 重载运算符时 要保持语义上的一致性 例如 重载运算符 时 仍应对有关对象执行加法运算 当然 也可以定义为其它某种运算 但这样做既没有必要 也容易造成混乱 C 规定 四种运算符必须重载为类运算符 10 10 2赋值运算符和四则运算符的重载 对名为T的类 其赋值运算符重载函数的格式如下 Toperator T 重载为非类成员运算符四则运算符属于二元运算符 也可以使用这两种形式 下面仍以复数运算为例 说明赋值运算符和四则运算符的重载 例10 4 复数的四则运算见教材P138 11 10 3自增1和自减1运算符重载 自增1运算符 和自减1运算符 都各有两种形式 前缀 前运算 和后缀 后运算 例如 a是前运算符 在进行其他运算前 变量a首先增1 a 是后运算符 做完其他运算后 a才增1 这四种形式的每一种都可以重载 增1运算符和减1运算符都只有一个操作数 通常被重载为类运算符 一元类运算符重载函数的参数表理应没有参数 操作数即是类对象本身 但为了区分前运算和后运算这两种形式 C 中规定 前运算符重载函数的参数表没有参数 后运算符重载函数的参数表设一个整数参数 这个参数称为哑元 只作为一个标志 用以区别前运算符 所以 对名为T的类 重载前运算符和后运算符的函数原型取如下格式 Toperator 重载前增1运算符Toperator int 重载后增1运算符Toperator 重载前减1运算符Toperator int 重载后减1运算符为了说明增1运算符和减1运算符重载 下面给出一个分数类作自增 自减的例子 例6 5 分数类的自增 自减 见教材P142 12 10 4关系运算符的重载 在C 中对于使用内部数据类型定义的变量 可以使用六个关系运算符 和 进行比较运算 而要对自定义类定义的变量进行比较运算 用户就必须重载这些运算符 下面以分数的 为例说明关系运算符的重载 例10 6 比较两个分数大小 输出值大的分数 见教材P144 13 10 5算术赋值运算符的重载 在C 中允许把算术运算符和赋值运算符组合在一起使用 这种书写方法简洁高效 同样也可以在自定义类型中重载这些运算符 为了简单起见 仍然使用分数的例子 例10 7 分数的加法运算 见教材P145 14 10 6下标运算符的重载 下标运算符通常用于数组 c 也允许重载这个运算符 在重载这个运算符时 需要注意的是 当 运算符位于 左边时 是修改数组中元素的值 需要返回这个元素的指针或引用 当 运算符位于 右边时 是取得数组中元素的值 需要返回这个元素的值或引用 为了能使 运算符即可用于 左边 也可用于 右边 在重载 运算符时 必须返回该元素的引用 下面给出一个数组类的例子来说明这一问题 例10 8 一个数组类的例子 见教材P147 15 10 7插入与抽取运算符的重载 10 7 1插入运算符的重载C 中对左移运算符 进行重载 以便输出C 内部类型的数据 对于自定义类型也可以重载运算符 按照合适的方式输出自定义类型的对象 下面以分数的输出为例介绍 例10 9 分数的输出 见教材P149 16 10 7 2抽取运算符的重载 C 中对右移运算符 进行重载 以便把外来的信息输入到所有的C 内部数据类型的变量 这些重载函数作为系统类的成员函数 例如 如果i是一个整型变量 C 便将输入语句cin i 翻译为cin operator i 然后调用此函数 读取一个值 存入变量i中 为了支持自定义类型 用户应重载输入运算符 在重载时 如果作为一般的函数来定义 而非类的成员函数 则这个重载运算符在被使用时应被声明为类的友元运算符 因为 的第一个操作数是系统类的对象cin 系统类iostream的对象 因此 作为友元函数 类X的输入运算符重载函数的原型应为 istream请注意 这个函数的第一个参数是输入流的引用 第二个参数是类X的引用 函数返回输入流的引用 其目的是为了能连续输入 对此 可以仿照6 7 1节做出解释 例10 10 分数的输入 见教材P151 17 10 8类型转换 在C 中 当使用数值类型进行计算时 各种类型之间可以隐式或强制转换 例如 doubled inta 2 d a 5 3 这种书写方式 使代码看起来优雅而自然 在用户自定义类中 没有进行类似的定义而无法使用这种方法 18 10 8 1基本类型转换和自定义类型的相互转换 在定义了类型转换后 对所有TRangeInt类型变量的计算都可以先转换成int类型 再进行计算 因此 可以不需要进行运算符的重载 如下面例子中的 运算符 例10 11 TRangeInt类型的加 减运算 见教材P154 19 10 8 2自定义类型之间的转换 有两种方法可以实现自定义类型之间的转换 使用类型转换符函数和构造函数 不仅可以在基本类型转换和自定义类型之间实现类型的转换 也可以在两个自定义类型之间实现 例10 12 使用类型转换符函数实现二维向量类型和复数类型的相互转换 见教材P155 20 例10 13 使用构造函数实现二维向量类型和复数类型的相互转换 程序见教材P157 21 10 9类模板与模板类 在编写程序时 有许多类的工作机制是相同的 只是其使用的数据类型不同 链表就是一个较为典型的例子 可以有整型链表 结构链表或自定义类的链表 但就链表本身的操作来说是相同的 在链表操作时 如果能够把要处理的类型当作参数 就可以构建一个通用的链表类 类模板的定义格式如下 templateclass类名 22 这里template是指出在所定义的类中 将使用到一个参数的类型为T 编译时 类型T将被调用时的具体类型替换 产生一个具体的类 称为模板类 由模板产生的类 来看一个具体的例子 单向链表 其结构图6 1所示 这里的数据可以是任意类型的 而对于任一个单向链表 其操作都是相同的 单向链表都具有增加 删除 寻找 遍历等操作 图10 1单向链表 23 例10 14 通用链表类的定义 程序见教材P159 24 本章小结 本章介绍了C 中 运算符重载和类型转换的概念 举例说明了运算符重载和类型转换的用法 使用运算符重载可以使程序易于理解并易于对对象进行操作 几乎所有的C 运算符都可以被重载 如果在类中没有说明本身的拷贝构造函数和赋值运算符 编译程序将会提供 但它们都只是对对象进行成员浅拷贝 this指针指向当前的对象 它是所有成员函数的不可见的参数 在重载运算符时 经常返回this指针的间接引用 25 在实际应用中应注意以下几点 设计和实现使用重载运算符 需要深入了解语言 运算符和类 合理地使用运算符重载 使它成为程序设计的有力工具 不要仅仅为了证明语言的威力而使用重载运算符 不能改变运算符操作数的数量 大多数运算符属于某个运算符系列 如果实现了系列中的某个成员 则需要实现其他的成员 以保持接口完整性和一致性 任何不需要左值并具有交换性的运算符都最好作为非成员函数 等 实现 这允许编译器在参数不匹配的情况下对第t个参数进行转换 任何需要左值的运算符最好作为成员函数实现 这明确说明它只能在现存的 可以修改的对象上调用 26 通过转换运算符可以在表达式中使用不同类

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论