




已阅读5页,还剩70页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第4章类和对象 二 4 1自引用指针this当定义了一个类的若干个对象后 每个对象都有属于自己的数据成员 但所有对象的成员函数代码却合用一份 成员函数是怎样辨别当前调用自己的是那个对象 从而对当前调用自己的对象的数据成员进行操作 例4 1this指针的引例 includeclassA public A intx1 x x1 voiddisp cout x x endl private intx main Aa 1 b 2 cout a a disp cout b b disp return0 this指针 this指针是每个对象中隐藏的指针 this指针是默认的 当一个对象生成后 这个对象的this指针就指向内存中保存该对象数据的存储空间的首地址 在类的成员函数中使用这个this指针 就好像this指针是类的一个自动隐藏的私有成员一样 当通过一个对象调用成员函数时 系统先将该对象的地址赋给this指针 然后调用成员函数 成员函数对对象的数据成员进行操作时 隐含使用了this指针 例4 2显示this指针的值 includeclassA public A intx1 x x1 voiddisp coutx private intx main Aa 1 b 2 c 3 a disp b disp c disp return0 includeclassSample private intx y public Sample inti 0 intj 0 x i y j voidprint cout x y endl voidcopy Sample 例4 3 操作该成员函数的对象的地址 操作该成员函数的对象 说明this指针是一个const指针 不能在程序中修改或赋值 this指针是一个局部数据 其作用域仅在一个对象内部 4 2对象数组与对象指针 4 2 1对象数组所谓对象数组是指每一数组元素都是对象的数组 定义一个一维数组的格式如下 类名数组名 下标表达式 访问的一般形式为 数组名 下标 成员名 例4 4对象数组的应用 includeclassexam public voidset x intn x n intget x returnx private intx main examob 4 inti for i 0 i 4 i ob i set x i for i 0 i 4 i cout ob i get x cout endl return0 例4 5通过初始化表给对象数组赋值 includeclassexam public exam x 123 exam intn x n intget x returnx private intx main examob1 4 11 22 33 44 examob2 4 55 66 examob3 4 exam 11 exam 22 exam 33 exam 44 4 2 2对象指针 1 用指针访问单个对象成员声明对象指针的一般语法形式为 类名 对象指针名 当用指向对象的指针来访问对象成员时 要用 操作符 例4 7对象指针的使用 includeclassexe public voidset a inta x a voidshow a coutshow a 利用对象指针访问对象的成员return0 2 用对象指针访问对象数组 例如将例4 7的main 改写为 main exeob 2 p ob 0 set a 10 ob 1 set a 20 p ob p show a p p show a return0 3 指向类成员的指针 通过指向成员的指针只能访问公有成员声明指向成员的指针声明指向公有数据成员的指针类型说明符类名 指针名 声明指向公有函数成员的指针类型说明符 类名 指针名 参数表 指向数据成员的指针初始化 说明指针应该指向哪个数据成员数据成员指针名 类名 数据成员名 通过对象名 或对象指针 与成员指针结合来访问数据成员对象名 数据成员指针名或 对象指针名 数据成员指针名 指向函数成员的指针初始化 说明指针应该指向哪个成员函数成员函数指针名 类名 函数成员名 成员函数指针名 类名 函数成员名 通过对象名 或对象指针 与成员指针结合来访问函数成员 对象名 成员函数指针名 参数表 或 对象指针名 成员函数指针 参数表 表 例4 9访问对象的公有数据成员的几种方式 includeclassA public A inti z i intz voidmain Aob 5 A pc1 pc1 例4 10访问对象的公有成员函数的几种方式 includeclassCoord public Coord inta 0 intb 0 x a y b intgetx returnx intgety returny private intx y voidmain Coordop 5 6 Coord pc1 4 3向函数传递对象 4 3 1使用对象作为函数参数向函数传递对象时 是通过传值调用传递给函数 因此 函数中对对象的任何修改均不影响调用该函数的对象本身 例4 11使用对象作为函数参数 includeclassaClass public aClass intn i n voidset intn i n intget returni private inti voidsqr aClassob ob set ob get ob get cout copyofobjhasivalueof cout ob get n main aClassobj 10 sqr obj cout But obj iisunchangedinmain cout obj get return0 4 3 2使用对象指针作为函数参数使用对象指针作为函数参数可以实现传址调用 即可在被调用函数中改变调用函数的参数对象的值 当函数形参是对象指针时 对应的实参应该是对象的地址值 例4 12使用对象指针作为函数参数 includeclassaClass public aClass intn i n voidset intn i n intget returni private inti voidsqr aClass ob ob set ob get ob get coutget n main aClassobj 10 sqr 4 3 3使用对象引用作为函数参数使用对象引用作为函数参数实现的也是传址调用 但比对象指针更简单 更直接 建议使用引用 例4 13使用对象引用作为函数参数 includeclassaClass public aClass intn i n voidset intn i n intget returni private inti voidsqr aClass 4 4静态成员 例4 14静态数据成员的引例 classStudent public Student char name1 char stu no1 floatscore1 Student voidshow 输出姓名 学号和成绩voidshow count sum ave 输出人数 总成绩private 和平均成绩char name 学生姓名char stu no 学生学号floatscore 学生成绩intcount 统计学生人数floatsum 统计总成绩floatave 统计平均成绩 Student Student char name1 char stu no1 floatscore1 name newchar strlen name1 1 strcpy name name1 stu no newchar strlen stu no1 1 strcpy stu no stu no1 score score1 count 累加学生人数sum sum score 累加总成绩ave sum count 计算平均成绩 Student Student delete name delete stu no count sum sum score voidmain Studentstu1 Liming 990201 90 stu1 show stu1 show count sum ave Studentstu2 Zhanghao 990202 85 stu2 show stu2 show count sum ave 4 4 1静态数据成员在一个类中 若将一个数据成员说明为static 这种成员称为静态数据成员 与一般的数据成员不同 无论建立多少个类的对象 都只有一个静态数据的拷贝 从而实现了同一个类的不同对象之间的数据共享 定义静态数据成员的格式如下 static数据类型数据成员名 例4 15静态数据成员的使用引例 include includeclassStudent public Student char name1 char stu no1 floatscore1 Student voidshow 输出姓名 学号和成绩voidshow count sum ave 输出学生人数 总成绩和平均成绩private char name 学生姓名char stu no 学生学号floatscore 学生成绩staticintcount 静态数据成员 统计学生人数staticfloatsum 静态数据成员 统计总成绩staticfloatave 静态数据成员 统计平均成绩 Student Student char name1 char stu no1 floatscore1 name newchar strlen name1 1 strcpy name name1 stu no newchar strlen stu no1 1 strcpy stu no stu no1 score score1 count 累加学生人数sum sum score 累加总成绩ave sum count 计算平均成绩 Student Student delete name delete stu no count sum sum score voidStudent show cout nname name cout nstu no stu no cout nscore score voidStudent show count sum ave cout ncount count 输出静态数据成员countcout nsum sum 输出静态数据成员sumcout nave ave 输出静态数据成员ave intStudent count 0 静态数员count初始化floatStudent sum 0 0 静态数员sum初始化floatStudent ave 0 0 静态数员ave初始化 voidmain Studentstu1 Liming 990201 90 stu1 show stu1 show count sum ave Studentstu2 Zhanghao 990202 85 stu2 show stu2 show count sum ave 静态成员count 静态成员sum 静态成员ave 说明静态数据成员的定义要加上关键字static静态数据成员的初始化应在类申明之后 定义对象之前 在类外单独进行 初始化格式为 数据类型类名 静态数据成员名 值静态数据成员属于类 而不像普通数据成员那样属于某一对象 因此可以使用以下方式访问静态数据成员 类名 静态数据成员名 说明静态数据成员与静态变量一样 在编译时创建并初始化 它在该类的任何对象被建立之前就存在 因此 公有的静态数据成员可以在对象定义之前被访问 对象定义后 也可以通过对象访问公有的静态数据成员 访问格式为 对象名 静态数据成员名对象指针 静态数据成员名私有静态数据成员不能被类外部函数访问 也不能用对象进行访问 C 支持静态数据成员的一个主要原因是可以不必使用全局变量 依赖于全局变量的类几乎都是违反面向对象程序设计的封装原理 4 4 2静态成员函数 静态成员函数属于整个类 是该类所有成员共享的成员函数 定义静态成员函数的格式如下 static返回类型静态成员函数名 参数表 与静态数据成员类似 调用公有静态成员函数的一般格式有如下几种 类名 静态成员函数名 实参表 对象 静态成员函数名 实参表 对象指针 静态成员函数名 实参表 例4 18静态成员函数来访问静态数据成员 include includeclassStudent private char name 学生姓名char stu no 学生学号floatscore 学生成绩staticintcount 静态数据成员 统计学生人数staticfloatsum 静态数据成员 统计总成绩public Student char name1 char stu no1 floatscore1 Student voidshow 普通成员函数 输出姓名 学号和成绩staticvoidshow count sum 静态成员函数 输出学生人数和总成绩 voidStudent show count sum 静态成员函数 cout ncount count 输出静态数据成员cout nsum sum 输出静态数据成员 intStudent count 0 静态数据成员初始化floatStudent sum 0 0 静态数据成员初始化 voidmain Studentstu1 Liming 990201 90 stu1 show Student show count sum 使用类名访问静态成员函数Studentstu2 Zhanghao 990202 85 stu2 show stu2 show count sum 使用对象stu2访问静态成员函数 说明静态成员函数可以定义为内嵌 也可以在类外定义 在类外定义时不能加关键字static一般情况下 静态成员函数主要用来访问全局变量或同一类中的静态数据成员 私有静态成员函数不能被类外部函数和对象访问 静态成员函数可在建立任何对象之前处理静态数据成员 普通成员函数则不能 说明编译系统将静态成员函数限定为内部连接 也就是说 与现行文件相连接的其它文件中的同名函数不会与该函数发生冲突在一般的成员函数中都隐含一个this指针 用来指向对象本身 而静态成员函数则没有this指针静态成员函数一般不访问类中的非静态成员 若确实需要 静态成员函数只能通过对象名 或指向对象的指针 访问非静态成员 例4 19静态成员函数访问非静态数据classsmall cat private doubleweight staticdoubletotal weight staticdoubletotal number public small cat doublew staticvoiddisplay small cat 4 4 3通过普通指针访问静态成员 例4 20通过指针访问类的静态数据成员 includeclassmyclass public myclass 构造函数 每定义一个对象 i 静态数据成员i加1staticinti 声明静态数据成员i intmyclass i 0 静态数据成员i初始化 不必在前面加staticmain int count 请注意声明和使用指向类的静态数据成员的指针与P95页中声明和使用指向类的非静态数据成员的指针的不同之处 int count 指向类的一般成员 count 通过指针直接访问静态数据成员ob2 count 通过对象和指针访问非静态数据成员 例4 21通过指针访问类的静态成员函数 includeclassmyclass public myclass i staticintgeti returni private staticinti intmyclass i 0 main int get myclass geti myclassob1 ob2 ob3 cout myclass i get endl return0 例通过指针访问类的普通成员函数 includeclassmyclass public myclass i intgeti returni private staticinti intmyclass i 0 main int myclass get get 4 5友元 友元是一扇通向私有成员 保护成员 的后门 友元既可以是不属于任何类的一般函数 也可以是另一个类的成员函数 还可以是整个的类 4 5 1友元函数 友元函数不是当前类的成员函数 而是独立于当前类的外部函数 但它可以访问该类的所有对象的成员 包括私有成员 保护成员和公有成员 例4 22友元函数的使用 classgirl public girl char n intd name newchar strlen n 1 strcpy name n age d friendvoiddisp girl 调用友元函数 说明友元函数不是成员函数 在类外部定义友元函数时不必在函数名前加上 类名 友元函数一般带有一个该类的入口参数 当一个函数需要访问多个类时 友元函数就显得非常重要 使用友元函数虽然提高了效率 但与面向对象的程序设计思想相背 应当谨慎使用 例4 23一个函数同时定义为两个类的友元函数classboy 前向引用classgirl public voidinit charN intA friendvoidprdata girlplg boyplb 声明友元函数 classboy public voidinit charN intA friendvoidprdata girlplg boyplb 声明友元函数 voidmain prdata G1 B1 调用友元函数 4 5 2友元成员 一个类的成员函数也可以作为另一个类的友元 这种成员函数不仅可以访问自己所在类对象中的所有成员 还可以访问friend声明语句所在类对象中的所有成员 这样能使两个类相互合作 协调工作 完成某一任务 例4 24一个类的成员函数作为另一个类的友元 include includeclassgirl 前向引用classboy public boy char n intd name newchar strlen n 1 strcpy name n age d voiddisp girl classgirl public girl char n intd name newchar strlen n 1 strcpy name n age d friendvoidboy disp girl 访问girl类对象的成员 voidmain boyb ChenHao 25 girle ZhangWei 18 b disp e 调用友元函数 说明一个类的成员函数作为另一个类的友元函数时 必须先定义这个类 并且在申明友元函数时要加上成员函数所在类的类名 如 friendvoidboy disp girl 4 5 3友元类 一个类也可以作为另一个类的友元例如 classY classX friendY 声明类Y为类X的友元类 当一个类被说明为另一个类的友员时 它的所有成员函数都成为另一个类的友员函数 说明友元关系是单向的 不具备交换性即若AB 并不等于BA友元关系不具有传递性即若AB BC 并不能推出AC 4 6对象成员 类的组合 在现实世界中 我们解决复杂的问题时 通常采用将其层层分解为简单问题的方法 即可将一个复杂的问题分解为几个较简单的子问题描述出来 而这些子问题又可以进一步分解 由更简单的子问题来描述 这样 只要这些最基本 最简单的子问题得以描述和解决 由它们构成的复杂问题就迎刃而解了 同样的思想可应用于面向对象的程序设计方法中 确定一个对象的内部结构可能是很困难的一件事 但我们可以通过将复杂对象层层分解为若干简单的 部件 对象的组合 然后再由这些易于描述和实现的部件对象来 装配 复杂对象 C 中允许将一个已定义的类的对象作为另一个类的数据成员 这称之为类的组合 即类可以将其它类对象作为自己的成员 形成一种包含和被包含的关系 ClassA private public ClassB private Aa public 其中 B类中的数据成员a就是一个A类的对象 称之为对象成员 在定义一个类时 其数据成员既可以是简单类型 又可以是自定义类型 还可以是类的对象 这样 我们定义类时 就可以利用已定义的类来构成新类 由若干结构简单 易于实现的类来构造复杂的类 这种类似于部件组装的方法 不仅简化了问题的描述 而且有利于提高软件的开发效率 也是软件复用的一种形式 对组合类 当创建该类的对象时 其中包含的各个对象成员也将被自动创建 故该类的构造函数应包含对其中对象成员的初始化 通常采用成员初始化列表的方法来初始化对象成员 在成员初始化列表中 既包含对对象成员的初始化 又包含对本类中其它的基本数据成员的初始化 下面通过一个例子简单说明成员初始化列表的构造 例 includeclassA private inta1 a2 public A inti intj a1 i a2 j voidprint cout a1 a2 endl classB private Aa intb public B inti intj intk a i j b k voidprint voidB print a print cout b endl voidmain Bb 3 4 5 b print 运行结果 3 45 总结如有以下的组合类 classX 类名1对象成员名1 类名2对象成员名2 类名n对象成员名n 则类X的构造函数的定义形式为 X X 对象成员所需的形参 本类成员形参 对象成员名1 形参表1 对象成员名n 形参表n 构造函数体 构造函数调用顺序 先调用内嵌对象的构造函数 按内嵌时的声明顺序 先声明者先构造 然后调用本类的构造函数 析构函数的调用顺序相反 若调用默认构造函数 即无形参的 则内嵌对象的初始化也将调用相应的默认构造函数 构造函数的两种定义形式 X X 对象成员所需的形参 本类成员形参 对象成员名1 形参表1 对象成员名n 形参表n 构造函数体 X X 类1对象1 类n对象n 本类成员形参 对象1 形参表1 对象n 形参表n 构造函数体 1 2 构造函数的两种使用形式 X对象名 实参表1 实参表n 本类成员实参表 类1对象1 实参表1 类n对象n 实参表n X对象名 对象1 对象n 本类成员实参表 1 2 那种形式好 4 7常类型 4 7 1常引用如果在说明引用时用const修饰 则被说明的引用为常引用 常引用的说明形式如下 const类型说明符其中 b是一个常引用 它所引用的对象不允许更改 例4 28常引用作函数形参 includeintadd constint 4 7 2常对象 如果在说明对象时用const修饰 则被说明的对象为常对象 常对象的说明形式如下 类名const对象名 参数表 或
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 药剂消费者需求研究试题及答案
- 2024年长沙市金海高级中学教师招聘笔试真题
- 西医临床中医结合应用试题及答案
- 2024年新疆大学招聘事业单位工作人员笔试真题
- 刀具行业未来发展与市场潜力分析
- 药剂类考试辅导资源试题及答案
- 药剂专业考试挑战试题及答案
- 规避错误2025年临床执业医师考试试题及答案
- 激光技术实务与理论考题试题及答案
- 药剂师必需的职业技能考题试题及答案
- 简约喜庆元宵节介绍模板 教学课件
- TCCIAT 0043-2022 建筑工程渗漏治理技术规程
- 西藏林芝嘉园小区项目可研(可研发)
- GB∕T 14527-2021 复合阻尼隔振器和复合阻尼器
- 航运系统组成和航运企业组织结构及特点
- 丧假证明模板
- 隧道二衬、仰拱施工方案
- 按期取得毕业证和学位证承诺书
- Q∕GDW 12106.4-2021 物联管理平台技术和功能规范 第4部分:边缘物联代理与物联管理平台交互协议规范
- 第五章 学校教育的主要活动形式:课堂教学
- 大会—冠脉微循环障碍
评论
0/150
提交评论