




已阅读5页,还剩32页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1 一 浅拷贝和深拷贝二 只读成员函数三 友元friend 第16章数据的共享和流通 2 一 浅拷贝和深拷贝对象作为数据的集合 其中有些数据需要与变量进行流通 有些数据需由不同的对象共享 本章介绍的深拷贝 友元函数 静态成员和指向成员的指针就是在不同的方面加快信息流动以及实施对象的保护的 3 存在两种形式的类 一种形式的类中仅存在变量或对象 不具备指针成员 缺省的拷贝构造函数和赋值运算符函数是浅拷贝的方式 该方式通过memcpy函数将源实例的数据复制给目标实例占住的一片内存空间 对于这样的类 缺省的浅拷贝方式是安全的 另一种形式的类含有指针成员 浅拷贝不再胜任这样的类 4 考虑如下说明 从上可见对于存在指针成员的类 系统提供的浅拷贝导致指针指向的内存为两个对象共享的格局 一个CDeep类的声明和对象定义 对象a b的内存和指针成员动态扩展的内存空间b a导致 b p a p b n a n 指针b p指向a对象的动态内存 classCDeep intn int p a b 中间深资源归口两个对象监控 5 浅拷贝的不良结果是 b p原先指向的堆空间悬空 既无法索引也不能收回这片内存 a或b对象的析构函数诱发中间共享的深资源的流失 对于凡是具有指针成员的类 应细致提交两个函数 一 是拷贝构造函数 二 是赋值运算符函数 以便进行指针成员的动态资源的深拷贝 深拷贝的核心思路是 1 目标对象与源对象内存空间独立 相应指针成员指向的内存空间也彼此独立 2 全部拷贝源对象的数据到目标对象 包括分别拷贝指针成员指向的内存数据 6 例 深拷贝方式 去掉定制的拷贝构造函数和赋值运算符函数则变成缺省的浅拷贝 include includeclassCDeep public intn int p CDeep int CDeep CDeep constCDeep 7 CDeep CDeep staticints num 1 printf d CDeep t s num delete p CDeep CDeep intk n k p newint n CDeep 8 CDeep CDeep constCDeep 9 程序输出 88 1 CDeep 666 bfadeoutaway 88 2 CDeep 3 CDeep 删除上面的拷贝构造函数和等号赋值运算符函数时 程序运行输出 88 1 CDeep 666 bfadeoutaway 572662307 2 CDeep 3 CDeep 之后弹出一个DebugAssertionFailed 的警告对话框 原因在于b对象退出作用范围后导致析构函数的调用 析构函数释放原来由a对象拥有的深部堆中资源 其后对该内存空间的操作a d 0 就等于在没有定义的内存空间进行寻址访问 因而是运行时的错误 10 二 只读成员函数volatile mutable关键字1 只读成员函数未经const或volatile限制的对象或成员函数是普通的对象或普通的成员函数 依称为对象或成员函数 只读对象是关键字const限定的对象 只读成员函数是const置于成员函数右圆括号之后修饰的成员函数 该成员函数不修改成员变量的数据状态 即成员函数体中出现的数据成员仅作为右值 没有只读的构造函数和析构函数 只读对象和对象都调用同一构造函数和析构函数 11 const用于名称细分 成员函数声明和定义都必须紧跟const关键字 只读成员函数的声明和定义格式为 其中type t1 t2 tn是已经声明的类型 typef t1v1 t2v2 tnvn const typeCType f t1v1 t2v2 tnvn const 成员函数可存在两个重载版本 一个只读版本另一个普通版本 当两种版本并存时 对象优先调用普通的成员函数 只读对象或只读的对象引用仅仅调用只读成员函数 12 对象可调用只读成员函数 关键字const本质上约束this形参为只读属性 只读指针形参可以匹配左值区的地址 普通指针形参不指向右值区的地址 只读对象的地址是右值区的地址 只读对象和只读成员函数不调用普通成员函数 普通的成员函数可调用只读成员函数 只读成员函数是只读取对象的数据状态的成员函数 13 例 const对象与只读成员函数 includestructCPoint longx longy classCRect public CRect intl intt intr intb CPoint 14 inlineCPoint 输出 left 10 top 20left 15 top 25 15 成员函数TopLeft存在只读的和非只读的版本 其中的语句是一样的 返回引用的函数可以作为左值 本来只读成员函数不改变对象的数据状态 如果不在返回类型上加const限制将导致对象外部调用对数据的改变 于是返回引用的只读成员函数在返回类型上由const前置限制 d TopLeft 为只读对象d调用只读成员函数 r TopLeft 为对象r调用普通的成员函数 16 2 volatile关键字volatile关键字表示内存数据的变更 volatile关键字和const关键字的语法是一致的 const修饰的变量维持恒定或函数不改变相关成员的数据状态 与const相反 volatile关键字限定的对象或成员函数可以有效的变动 这种变动可以来自其它的外部进程 17 例 volatile关键字的用法 includeclassB volatileintm n public B intv 1 m n v voidSet intn volatile m n n voidShow const printf Show const n d n m n voidShow volatile printf Show volatile n d n m n voidShow printf Show n d n m n 18 voidmain constBc c Show volatileBv 2 v Show v Set 3 v Show Bx 4 x Show 程序输出结果 Show const n 1 Show volatile n 2 Show volatile n 3 Show n 4 19 volatile对象操作volatile成员函数 const对象操作const成员函数 不妨认为volatile关键字和const关键字是一对含意相反的语法修饰词 它们常称为c v限定词 对象既可操作const成员函数也可操作volatile成员函数 如果这两个成员函数都存在但不存在普通的版本则导致调用的歧义 volatile关键字使用的场合在一般程序中不多 主要用在系统的程序设计中 volatile关键字可以和const同时出现 如下 volatileconstintg n 1 这表示程序不能改变变量g n的值 但允许系统改变它 20 3 mutable关键字关键字mutable可以局部松动const对象的不变属性 如果一个对象前加上const关键字限制 则这个对象所有的成员就冻结为右值 但有时候对于这种约束期望有所放松 此时只需在相关的成员前冠以mutable修饰 通知编译器如此成员不受const的制约 21 例 mutable关键字注册绝对可变的成员 includeclassCType public mutablelongv longn voidmain constCTypecobj 1 2 printf cobj d d t cobj v cobj n cobj v 8 printf cobj d d n cobj v cobj n cobj n 2 error l valuespecifiesconstobject 输出结果 cobj 1 2 cobj 8 2 22 上面的代码中v是一个绝对可变的成员 n是一个相对可变的成员 n受const对象限制时而间接的成为右值表达式 对于本题cobj是一个不变对象 因而cobj n不能成为左值 v由于有了mutable的特殊关照 cobj v则构成左值表达式 23 三 友元friendfriend声明的函数称为友元函数 friend可用于声明一个类 这个类称为友元类 友元函数细分为全局友元函数和成员友元函数 友元函数或友元类在所访问类或当前类中由friend声明 格式为 classCN private friendTf T1 CN 类型名称type T T1 T2 Tn A B在使用点之前应首先说明 24 friend关键字无视protected private的制约 放置在类声明的任何地方是等效的 友元可访问当前类的所有成员 友元类所有的成员函数都是友元函数 友元类或友元函数一般通过三个途径访问当前类所有的成员 包括公共属性的保护属性的和私有属性的成员 a 友元函数的入口形参具有当前类的类名 b 友元函数具有当前类的对象作为局部对象或对象指针作为局部指针 c 友元类具有当前类的对象作为其嵌入成员对象 25 1 友元函数友元函数是一种定义在当前类外部的普通函数 通过friend在当前类内部声明 但友元函数不是当前类的成员函数 在当前类的友元函数获得如此特权 定义在友元函数形参列表或函数体中的当前类对象 对象引用或对象指针等可以访问该类所有控制属性的成员包括私有成员 就好像当前类三个访问控制属性全部是公共的访问控制属性 26 友元是一种解除访问控制约束的机制 此种破除访问控制约束的友元关系不传递不反身不继承 即如果类A是类B的友元 类B是类C的友元 A不会自动称为类C的友元 类A是类B的友元但不一定类B是类A的友元 类A是类B的友元 类A的派生类D不会自动成为类B的友元 友元函数是某个类的特权函数 这个访问当前类所有成员的特权在该类中由friend声明获得 未由friend声明的函数操作当前类的公共成员 27 例 友元函数将类回归到经典的公共访问性质的结构 includestructS inte classB classA private inta public voidadd B 28 classB friendvoidswap A p B error b cannotaccessprivatemember 29 voidswap A p B 输出2 3 30 说明 类B的友元函数的声明格式为 classB friendvoidswap A p B A类的成员函数add是B类的友元函数其中值得关注的是当前类的类名B出现在友元函数的形参类型中 形参r可通过圆点运算符访问B类中的任一成员 同理全局函数swap A p B r 是类A的友元函数 这个函数的A 型形参p可以通过箭头运算符 访问A类的所有成员包括私有成员 31 友元函数或友元类由friend声明 但友元函数或友元类在当前类外的定义不使用关键字friend 友元函数的定义应位于当前类的描述之后 以便编译器必须有足够的信息操作当前的成员 友元函数的调用维持原来的格式 即全局友元函数按照全局函数的虚实结合匹配 成员友元函数则根据自身类的对象外部调用或自身类的this指针内部调用 另一个全局函数PublicB S p B r 由于不是类B的友元函数 B 型的引用形参r只能访问公共的成员 妨碍了数据的流通 为解决这种现象可以声明这个全局函数为B类的友元函数 通知编译器跳过成员属性访问控制检查的机制 抹平精细封装的界限 或者将B类的数据处理为公共的属性 32 2 友元类前面说明了友元函数在某一个类中的特权地位 在友元函数中当前类不过是一个毫不设防的公共世界 关键字protected和private形如虚设 一个类可以声明另一个类为其友元 由此形成友元类 友元类中的所有成员函数可以访问当前类所有的成员 33 例 友元类B将当前类A视为一个公共访问控制属性的结构 includeclassB classA friendclassB private intm a A intk 0 m a k public friendvoidg f v
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 兼职业务员合同范文5篇
- 同安区2025福建厦门市同安区卫生事业单位招聘20人笔试历年参考题库附带答案详解
- 南昌市2025年江西九江经济技术开发区第二批次招聘雇员4人笔试历年参考题库附带答案详解
- 内蒙古2025内蒙古大学教辅岗位招聘10人笔试历年参考题库附带答案详解
- 三明市2025福建三明市交通运输局直属事业单位选聘1人笔试历年参考题库附带答案详解
- 2025重庆市退出消防员首次安置市级双向选择选岗18人笔试参考题库附带答案详解
- 2025盛威安全设备(浙江)有限公司招聘14人笔试参考题库附带答案详解
- 2025浙江省安全生产科学研究有限公司招聘19人(杭州市)笔试参考题库附带答案详解
- 2025江苏苏州市苏惠优达供应链管理有限公司紧急招聘4人笔试参考题库附带答案详解
- 2025年锡林郭勒阿巴嘎旗城乡建设投资集团有限公司面向社会招聘12名工作人员笔试参考题库附带答案详解
- 甘肃省建设工程计价规则(DBJD25-98-2022)
- IDC机房机架装机管理作业指导书
- 2024年内蒙古人力资源和社会保障厅事业单位笔试真题
- 中医治未病健康宣教
- 食堂员工服务培训
- 提升心理抗压能力的技巧
- 中医医术确有专长人员(多年实践人员)医师资格考核申请表
- 低空飞行器设计
- 《穴位埋线疗法》课件
- 【大型集装箱船舶港口断缆事故预防应急处理及案例探析7500字(论文)】
- 三对三篮球赛记录表
评论
0/150
提交评论