第四章 类与对象.ppt_第1页
第四章 类与对象.ppt_第2页
第四章 类与对象.ppt_第3页
第四章 类与对象.ppt_第4页
第四章 类与对象.ppt_第5页
已阅读5页,还剩141页未读 继续免费阅读

下载本文档

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

文档简介

1 2 第四章类与对象 在C语言中 常用到一些数据结构以及处理这些数据结构的函数 但是由于C语言是面向过程的语言 并没有将这些相关的数据结构和函数构成一个有机的整体进行封装 从而无法对这些数据进行保护和访问权限的控制 同时对程序的可重用性等方面也不太重视 C 语言具有面向对象程序设计的特征 具有封装性 继承性 多态性等 在软件设计思想上从另一个角度来进行程序的设计 这是一个比较大的程序设计思路的改变 本章主要介绍类的构成 对象的创建与使用 构造函数与析构函数 友员成员 静态成员 对象成员 常数成员等内容 3 第四章类与对象 4 1类的构成 1 为什么定义类把现实世界的事物归纳成类 以贴近自然的方式描述现实系统 2 类的组成类由三个部份组成 类名 数据成员 属性 datamember 成员函数 服务 memberfunction 3 数据成员和成员函数分类公有数据成员和成员函数 供外部函数通过类的对象任意访问 作为用户接口 通常是一些成员函数 私有数据成员和成员函数 供类本身的函数和友员访问 用来描述该类对象的属性 通常为数据成员 保护数据成员和成员函数 供类本身的函数及派生类对象和友员访问 既有成员函数 也有数据成员 4 第四章类与对象 4 类的定义classclassName 以关键字class开头 public 类的公有成员datamembers 公有数据成员memberfunctions 公有成员函数protected 类的保护成员datamembers 保护数据成员memberfunctions 保护成员函数private 类的私有成员datamembers 私有数据成员memberfunctions 私有成员函数 以括号及分号结束 体现封装 类型缺省时为私有成员 private 类的定义以 为结束标记 类型符号后面的符号是 5 第四章类与对象 5 说明 1 类型缺省时为私有成员 应首先定义 类的定义以 为结束标记 类型符号后面的符号是 2 public protected private无顺序与次数限制 3 数据成员不能是本类对象 但可以是指向本类的指针或引用 数据成员的类型不能是auto register extern存储类型 如 classA classB private inta Aobja1 正确A obja2 正确B objb 6 第四章类与对象 4 定义类时不能为数据成员赋初值 因为定义类实质上是定义一种数据类型 不涉及存储空间的分配 如 classA private inta 0 错误intb 3 1 2 3 错误public 5 struct也是一种类 功能 用法都与class相同 惟一区别是不能指定各成员的访问权限 所有成员都具有public权限 7 第四章类与对象 例4 1类student的定义classstudent 定义类 public 类的公有成员voidinput char n char na floats 输入信息voidmodify floats 修改成绩voiddisplay 显示信息private 类私有成员char id 学号char name 姓名floatscore 成绩 在类中 数据成员是对类的静态特征的描述 而成员函数是对类的动态特征的描述 是类与外界的接口 8 第四章类与对象 4 2成员函数的定义1 成员函数在前面定义了student类 把这个类所在的文件称为student h 对于成员函数的定义可以放在同一个文件student h中定义 但是一般并不这样做 通常是将类的定义与类的实现分成两个不同的文件 对上例来说 就是student h和student cpp 9 第四章类与对象 例4 2文件student h ifndefSTUDENT H 条件编译 defineSTUDENT Hclassstudent 定义类 public 类的公有成员voidinput char n char na floats voidmodify floats voiddisplay private 类私有成员char id 学号char name 姓名floatscore 成绩 endif ifndefSTUDENT H endif是一个条件编译语句 防止多次包含带来的编译错误 10 第四章类与对象 例4 3文件student cpp include include include student h 必须包含类的定义voidstudent input char n char na floats 定义成员函数 id newchar strlen n 1 动态分配内存strcpy id n 字符串复制score s name newchar strlen na 1 strcpy name na 11 第四章类与对象 voidstudent modify floats score s 定义成员函数voidstudent display 定义成员函数 cout nid id cout nname name cout nscore score 12 第四章类与对象 例4 4文件main cpp include student h 包含类student的定义文件voidmain 主函数 studentss 声明对象charna WANGQIAN ss input 9901 na 88 5 调用成员函数ss display 调用成员函数 结果 id 9901name WANGQIANscore 88 5 注意 函数input的作用是为对象赋值 该例无构造函数 13 第四章类与对象 讨论 1 在一个项目中有三个文件 student h 类的头文件 student cpp 类的实现文件 main cpp 主文件 即应用程序 2 对类的成员函数的实现一般形式为 类型类名 成员函数 形式参数 函数体 如 voidstudent display 14 第四章类与对象 3 在头文件中应加入条件编译 以免多次包含 如 ifndefSTUDENT H endif 4 在类的定义文件中原则上也可以插入成员函数 但是一般应尽量不包含类的成员函数的实现 除非该成员函数的实现语句很少 15 第四章类与对象 5 将类的定义与实现分离开来的优点 把类的定义与实现分离开来 便于文档管理 维护 可将类的实现隐蔽起来 使软件开发商能独立开发软件 如果不分离 则所有的成员函数将作为内联函数处理 这是不合适的 便于团体式的大型软件开发 16 第四章类与对象 2 常量成员函数在C 中 为了禁止成员函数修改数据成员的值 可以将它设置为常量成员函数 形式如下 classx Tf const 例子 classEmployee char name doublesalary public 17 第四章类与对象 voidinit constchar Name constdoubley doublegetSalary const 常量函数 不能通过它修改name和salary 说明 只有类的成员函数才能定义为常量函数 普通函数不能定义为常量函数 下面的函数定义是错误的 intf intx const 错误 普通函数不能指定为constintb x x returnb 常量参数与常量成员函数是有区别的 常量参数限制函数对参数的修改 但与数据成员是否被修改无关 18 例 常数成员函数的应用 saveasemploy hclassEmployee public Employee constchar constchar 本函数中参数为常数 Employee char getName const 常数成员函数 不能修改类的数据成员char getID const private char name char ID saveasemploy cpp include include include employ h 19 Employee Employee constchar pname constchar pid name newchar strlen pname 1 strcpy name pname ID newchar strlen pid 1 strcpy ID pid char Employee getName const returnname 返回字符型指针 指向姓名name char Employee getID const returnID 返回字符型指针 指向身份证号ID 20 Employee Employee delete name delete ID saveasmain cpp include include employ h voidmain Employeeep Tang 100200300500600800 cout name ep getName endl cout ID ep getID endl 21 第四章类与对象 例4 4对象的声明及成员函数调用 include student h 包含类student的定义文件voidmain students1 s1 input 9902 Li 90 s1 display 公用成员函数s1 modify 95 公用成员函数s1 display 结果 id 9902name Liscore 90id 9902name Liscore 95 4 3对象的定义与使用一旦定义了对象之后 就可以通过调用它的成员函数来实现类的具体功能 1 通过对象名调用 22 第四章类与对象 例4 5通过指针调用 include student h voidmain students2 p 定义类student的对象s2 及指向该类型数据的指针pp 通过定义一个指向类student的指针p 成员函数的调用通过指针p来完成 2 通过指针调用 23 第四章类与对象 例4 6通过指针调用 include include student h voidfunc student ss ss display voidmain students3 定义类student的对象s3s3 input 9902 Li 90 调用公用成员函数func 对象的地址也可作为普通函数func 调用的参数 这里的普通函数是相对于成员函数而言的 24 第四章类与对象 例4 7通过引用调用 include include student h voidfunc student 错误 不能访问私有成员 3 通过引用调用 25 第四章类与对象 在类的定义中 公有成员可以由外部函数通过类的对象任意访问 保护成员只能由类本身的函数 继承类和友员来访问 私有成员则只能由类本身的函数和友员来访问 4 对象赋值可用C 缺省的对象赋值运算符 1 格式 对象名1 对象名2 如 Clock pa pb aClock bClock bClock aClock pa newClock 动态对象pb pa 2 说明 26 第四章类与对象 第一 两个对象必须类型相同 第二 赋值的功能是进行数据成员值的按位拷贝 赋值之后 两个对象两不相干 第三 若对象有指针数据成员 赋值可能产生内存漂浮和指针悬挂问题 例 Clock类及其对象的完整例程 include includeclassClock public voidsetHour inth hour h voidsetMinute intm minute m voidsetSecond ints second s 27 第四章类与对象 voiddispTime cout Nowis hour minute second endl private inthour minute second voidmain Clock pa pb aClock bClock aClock setMinute 12 aClock setHour 16 aClock setSecond 27 bClock aClock 28 第四章类与对象 pa newClock pa setHour 10 pa setMinute 23 pa setSecond 34 pb pa pa dispTime pb dispTime aClock dispTime bClock dispTime 29 第四章类与对象 4 4构造函数和析构函数 构造函数 创建对象时 初始化类的数据成员 析构函数 删除对象时 释放内存 回想一下变量和函数参数的初始化变量 定义与初始化赋值结合起来 intnumber 9902 函数 应用缺省参数初始化voidadd inta 0 intb 0 初始化目的 便于编程 保证变量的值不会无意义 减小程序出错的可能性 30 第四章类与对象 1 构造函数的特征 1 构造函数是与类同名的特殊成员函数 否则编译程序会将它视为一般的成员函数来处理 2 构造函数没有返回值 因此 在声明和定义构造函数时没有类型说明 3 构造函数的功能是对对象进行初始化 且一般只对数据成员进行初始化 4 构造函数不能像其它成员函数那样被显式地调用 它在对象被创建后的第一时间自动调用 5 构造函数可以被重载 6 定义对象数组或创建动态对象时也要调用构造函数 7 构造函数应定义为公有成员 因为它是在类外调用 31 第四章类与对象 2 无参构造函数无参构造函数 只负责按照预先的值进行初始化 下面是类定义文件student h的内容 例4 8构造函数的应用 saveasstudent hclassstudent public student student 32 第四章类与对象 voidchgName char pn voidchgId char pid voidchgScore floats voiddisplay private char name char id floatscore 33 第四章类与对象 saveasstudent cpp include include include student h student student name newchar 11 strcpy name id newchar 10 strcpy id 000000000 score 0 34 第四章类与对象 student student delete name 释放原空间delete id voidstudent chgId char pid delete id 释放原有空间id newchar strlen pid 1 strcpy id pid 35 第四章类与对象 voidstudent chgName char pn delete name name newchar strlen pn 1 strcpy name pn voidstudent chgScore floats score s voidstudent display cout nid id cout nname name cout nscore score endl 36 第四章类与对象 saveasmain cpp include student h voidmain students4 s4 display s4 chgName Yang s4 chgId B99060101 s4 chgScore 98 s4 display 37 第四章类与对象 3 有参构造函数利用带有参数的构造函数可以对类中的变量赋某个给定的值例4 9带参数构造函数的应用 saveasstudent hclassstudent public student student char pid char pn floats student voidchgName char pn voidchgId char pid voidchgScore floats voiddisplay 38 第四章类与对象 private char name char id floatscore saveasstudent cpp include include include student h student student name newchar 11 strcpy name id newchar 10 strcpy id 000000000 score 0 39 第四章类与对象 student student char pid char pn floats name newchar strlen pn 1 strcpy name pn id newchar strlen pid 1 strcpy id pid score s student student delete name delete id 40 第四章类与对象 voidstudent chgId char pid delete id id newchar strlen pid 1 strcpy id pid voidstudent chgName char pn delete name name newchar strlen pn 1 strcpy name pn voidstudent chgScore floats score s 41 第四章类与对象 voidstudent display cout nid id cout nname name cout nscore score endl saveasmain cpp include student h voidmain students4 s4 display s4 chgName Yang s4 chgId B99060101 s4 chgScore 98 s4 display students5 W99060109 Wang 88 s5 display 42 第四章类与对象 4 缺省参数构造函数利用带有参数的构造函数对类中的变量赋某个给定的值 但是在创建对象时必须指定所有参数的具体数值 这对于编程来说是不方便的 缺省参数的构造函数可以解决这个问题 例4 10缺省参数的构造函数 saveastime hclassTime public Time int 0 int 0 int 0 voidsetTime int int int voidprintMilitary 43 第四章类与对象 voidprintStandard private inthour intminute intsecond saveastime cpp include include time h Time Time inthr intmin intsec setTime hr min sec voidTime setTime inth intm ints 44 第四章类与对象 hour h 0 45 第四章类与对象 saveasmain cpp include include time h voidmain Timet1 t2 2 t3 21 34 t4 12 25 42 t5 27 74 99 cout Constructedwith endl allargumentsdefaulted endl t1 printMilitary cout endl t1 printStandard cout endl hourspecified minuteandseconddefaulted endl t2 printMilitary 46 第四章类与对象 cout endl t2 printStandard cout endl hourandminutespecified seconddefaulted endl t3 printMilitary cout endl t3 printStandard cout endl hour minuteandsecondspecified endl t4 printMilitary cout endl t4 printStandard 47 第四章类与对象 cout endl allinvalidvaluesspecified endl t5 printMilitary cout endl t5 printStandard cout endl 48 第四章类与对象 5 拷贝构造函数如果希望在创建一个对象时 用另一个已知的对象来初始化该对象 则可用C 缺省的拷贝构造函数来实现 如下例 students1 9901 XU 88 students2 s1 创建对象s2 并由s1去初始化s2 调用缺省拷贝构造函数 或 students2 s1 创建对象s2 并由s1去初始化s2 调用缺省拷贝构造函数 如果对象中无指针成员 以上两种方式均可 但如果对象中有指针成员 则将出现指针悬挂问题 由于S2 Name和S1 Name指向同一内存区域 当程序结束时 S2 Name首先被释放 从而使得S1 Name悬挂 再释放S1 Name时 使同一地址被释放两次 析构顺序与构造顺序相反 解决方法 定义显式拷贝构造函数 49 第四章类与对象 定义拷贝构造函数的一般形式为 class类名 public 类名 形参表 有参构造函数类名 const类名类名 类名 const类名 对象名 拷贝构造函数的实现 函数体 50 第四章类与对象 classpoint public point intxx 0 intyy 0 X xx Y yy 缺省参数构造函数 point constpoint 51 第四章类与对象 拷贝构造函数的实现如下 point point constpoint 原对象的x y 新对象的x y 52 第四章类与对象 当用类的一个对象去初始化该类的另一个对象时 voidmain pointA 1 2 调用有参构造函数初始化pointB A 调用拷贝构造函数初始化cout B GetX B GetY endl 结果 拷贝构造函数被调用1 2 53 第四章类与对象 6 构造函数个数原则上一个类可有多个构造函数 但是要保证在创建对象时调用构造函数的唯一性 即不能有多个构造函数被调用 如程序中同时定义了无参构造函数和带缺省参数的构造函数 则在创建对象时如果没有给出参数 就不知道该调用哪个构造函数 一般说来 如果定义了带缺省参数的构造函数 就没有必要再定义无参构造函数 54 例4 11平面点类point saveaspoint hclasspoint public 公有成员point 无参构造函数point floatx1 floaty1 有参构造函数point constpoint 点的纵坐标 类定义结束 55 saveaspoint cpp include point h point point x 0 y 0 无参构造函数point point floatx1 floaty1 有参构造函数 x x1 y y1 point point constpoint 56 saveasmain cpp include point h voidmain pointp1 调用无参构造函数 x 0 y 0pointp2 2 2 调用有参构造函数pointp3 p2 调用拷贝构造函数p1 move 5 5 p1 show p2 show p3 show 结果 Point x y 5 5 Point x y 2 2 Point x y 2 2 57 第四章类与对象 7 析构函数析构函数的功能是对类中动态分配的内存进行释放 它在删除对象时自动调用 其形式为 类名 如果用到了动态内存 且变量不是数组 其形式为 类名 delete变量名 如果用到了动态内存 且变量是数组 其形式为 类名 delete 数组名 58 第四章类与对象 8 讨论 默认拷贝构造函数引起指针悬挂问题的例子 include includeclassPerson private char name intage public Person char Name intAge Person voidsetAge intx age x voidprint 59 第四章类与对象 Person Person char Name intAge name newchar strlen Name 1 strcpy name Name age Age cout constructor endl Person Person cout destructor age endl delete name 60 第四章类与对象 voidPerson print cout name tTheAddressofname name endl voidmain Personp1 张勇 21 调用构造函数Personp2 p1 调用缺省拷贝构造函数 p2 name p1 namep1 setAge 1 p2 setAge 2 p1 print p2 print 61 第四章类与对象 程序的运行结果 constructor 张勇TheAddressofname 张勇张勇TheAddressofname 张勇destructor 2 释放p2destructor 1 释放p1同时弹出一个错误信息框 大意是程序试图删除一个空指针 原因 从结果看 构造函数调用了一次 而析构函数调用了两次 从而使得在析构p2之后 p1 name成为一个悬挂的指针 如下图所示 62 第四章类与对象 63 第四章类与对象 程序作如下更改 在类的定义中增加拷贝构造函数声明 在类的实现中实现即可 classPerson private char name intage public Person char Name intAge Person constPerson 64 第四章类与对象 Person Person constPerson 更改之后的运行情况 可以看出构造函数和析构函数都调用了2次 65 第四章类与对象 当程序中定义了拷贝构造函数之后 对象赋值时就不会再调用缺省拷贝构造函数了 从而解决了上述问题 拷贝构造函数说明 1 拷贝构造函数与一般构造函数相同 与类同名 没有返回类型 可以重载 2 拷贝构造函数的参数常常是const类型的本类对象的引用 3 在多数情况下 缺省拷贝构造函数能够完成对象的复制创建工作 但当类具有指针类型的数据成员时 缺省拷贝构造函数就可能产生指针悬挂问题 需要提供显式的拷贝构造函数 66 第四章类与对象 4 对拷贝构造函数的调用常在类的外部进行 应该将它指定为类的公有成员 5 调用拷贝构造函数的时机是用已存在的对象初始化同类的新对象 以下三种情况会导致拷贝构造函数的调用 classX 定义类XXobj1 Xobj2 obj1 情况1 调用拷贝构造函数Xobj3 obj1 情况2 调用拷贝构造函数f Xobj 情况3 以对象作函数参数时 调用拷贝构造函数但 Xobj1 obj2 obj2 obj1 只调用赋值运算符而不调用拷贝构造函数 67 第四章类与对象 9 构造函数与初始化列表构造函数还可以采用成员初始化列表的方式对数据成员初始化 而且在某些情况下只能采用初始化列表的方式才能完成数据成员的初始化 1 初始化列表形式成员初始化列表类似于下面的形式构造函数名 参数表 成员1 初始值1 成员2 初始值2 介于参数表后面的 与函数体 之间的内容就是成员初始化列表 其含义是将括号中的初始值赋给该括号前面的数据成员 68 第四章类与对象 例 用初始化列表初始化Tdate的month和day成员 includeclassTdate public Tdate intm intd inty 其他公共成员protected intmonth day year Tdate Tdate intm intd inty month m day d year y cout month day year endl voidmain Tdatebday2 10 1 2003 69 第四章类与对象 2 使用构造函数初始化列表的注意 构造函数初始化列表中成员的初始化 构造 次序与其在类中的声明次序相同 与其在初始化列表中的次序无关 如下面3个构造函数是完全相同的 Tdate Tdate intm intd inty month m day d year y Tdate Tdate intm intd inty year y month m day d Tdate Tdate intm intd inty day d year y month m 尽管三个构造函数初始化列表中的month day和year的次序不同 但它们都是按照其在类中的声明次序month day year的次序初始化的 构造函数初始化列表先于构造函数体中的语句执行 常量成员 引用成员 类对象成员 派生类构造函数对基类构造函数的调用必须采用初始化列表进行初始化 70 第四章类与对象 看看下面程序的运行结果 includeclassA inti j public A inta i j j a voiddiaplay cout i i t j j endl voidmain Ax 4 x diaplay 结果 i j 4 71 第四章类与对象 看看下面程序的运行结果 includeclassA constinti j int 前两个参数可以是常量 但不能将m直接写成6 结果 i 4j 5k 6 72 第四章类与对象 4 5友员1 为什么要定义友员类中的私有数据不能被外部任意访问修改 只能由类本身的函数访问修改 带来操作上的不便 2 友员的作用被定义为友员的类或函数可以访问并修改类的私有数据 3 友员的定义在类中定义 1 友员类friendclass友员类名 将一个类声明为另一个类的友员类 友员类的所有成员函数都是另一个类的友员函数 能够直接访问另一个类的所有成员 包括public private和protected 73 第四章类与对象 2 友员成员函数friend返回值类型类名 函数名 将一个类中的一些成员函数声明为另一个类的友员 即友员成员函数 友员成员函数可以直接访问另一个类的私有成员或保护成员 而不是友员的成员函数就只能通过公有成员函数访问其他类的私有和保护成员 3 友员函数friend函数原型声明 将普通函数声明为一个类的友员 即友员函数 友员函数可以直接访问类的私有成员或保护成员 例4 12未用友员 include includeclassst n char name num 学生姓名 学号 74 public st n char n1 char n2 name newchar strlen n1 1 num newchar strlen n2 1 strcpy name n1 strcpy num n2 voiddsp cout nname name nnum num 75 classsco intmat eng 学生数学 英语成绩 public sco inti1 inti2 mat i1 eng i2 初始化列表 voidshow cout nmathematics mat nenglish eng 76 voidmain st na Wang 123456 创建对象scob 72 82 创建对象a dsp 打印姓名 学号b show 打印数学 英语成绩 结果 name Wangnum 123456mathematics 72english 82 问题 定义了两个类的对象a b 但相互不能访问私有数据 把两个有联系的类割裂开了 77 应用友员重新定义类st n和sco 注意与前面类st n和sco的区别 include includeclassst n friendclasssco sco是st n的友员类char name num 学生姓名 学号 public st n char n1 char n2 name newchar strlen n1 1 num newchar strlen n2 1 strcpy name n1 strcpy num n2 例4 12声明为友员类 78 classsco intmat eng 学生数学 英语成绩 public sco inti1 inti2 mat i1 eng i2 voidshow cout nmathematics mat nenglish eng voidshow st n 友员类成员函数访问另一个类的私有数据成员 79 voidmain st na Wang 123456 创建对象scob 72 82 创建对象b show a 打印姓名 学号b show 打印数学 英语成绩 结果 name Wangnum 123456mathematics 72english 82 说明 定义了两个类st n sco 且sco的所有成员函数都能访问st n的私有数据 建立了类之间的联系 80 include includeclassst n 前向引用声明 因为此时st n未定义classsco intmat eng 学生数学 英语成绩 public sco inti1 inti2 mat i1 eng i2 voidshow cout nmathematics mat nenglish eng voidshow st n 例4 13使用友员成员函数 81 classst n friendvoidsco show st n sco show st n 是st n的友员成员函数 82 voidmain st na Wang 123456 创建对象scob 72 82 创建对象b show a 打印姓名 学号 成绩 结果 name Wangnum 123456mathematics 72english 82 说明 定义了两个类st n sco 类sco的成员函数show st n st 是类st n的友员 因此 该函数能访问类st n的私有数据 建立了类成员函数与类之间的联系 83 include includeclassst n char name num 学生姓名 学号friendvoidshow st n 例4 14使用友员函数 84 classsco intmat eng 学生数学 英语成绩public friendvoidshow all st n 85 voidmain st na Wang 123456 创建对象scob 72 82 创建对象show all a 打印姓名 学号 数学 英语成绩 结果 name Wangnum 123456mathematics 72english 82 说明 定义了两个类st n sco 且外部函数show st n st show all st n st sco p 分别是st n和sco的友员 因而它们能访问类的私有数据 建立了类与外部函数之间的联系 86 第四章类与对象 4 几点说明 1 友员关系不能传递 即A是B的友员 B是C的友员 但A不一定是C的友员 除非特别声明 2 友员关系不可逆 即A是B的友员 并不意味着B是A的友员 除非特别声明 3 以上这些都反映了现实世界的结构关系 是对对象的一种自然反映 所以 面向对象的程序设计在一定程度上是一种对自然社会关系的直接映射 87 第四章类与对象 4 6静态成员我们知道 创建了一个对象 则这个对象将拥有类中的所有成员 如果某个数据对所有对象都一样 则这个数据只要有一个拷贝就行了 而不是每个对象都重复定义这个数据 形成内存浪费 简言之 一个数据拷贝 所有对象共享 类的静态成员具有这种特性 静态成员是属于类的 整个类只有一份拷贝 相当于类的全局变量 能被该类的所有对象共享 类的静态成员遵守public protected private访问权限的限定规则 1 静态数据成员的声明classX static类型静态数据成员名 不分配内存空间 88 第四章类与对象 2 静态数据成员的定义格式1 类型类名 静态数据成员名 格式2 类型类名 静态数据成员名 初值 说明 1 静态数据成员通常在类外进行定义 2 静态数据成员定义时 其类型前面不能冠以static 3 静态数据成员可以指定初值 否则默认0值 4 静态数据成员的典型应用是统计相关类的对象个数 3 静态数据成员的访问 1 通过类名访问类名 静态数据成员名 2 通过对象访问对象名 静态数据成员名 89 例4 15静态数据成员的应用 saveasst n hclassst n char name num 学生姓名 学号 staticinttotal 学生总人数 声明为静态数据成员public st n char char st n voidprint saveasst n cpp include include include st n h intst n total 0 静态数据成员的定义 90 st n st n char n1 char n2 name newchar strlen n1 1 num newchar strlen n2 1 strcpy name n1 strcpy num n2 total 创建一个对象 学生人数加1voidst n print cout nname name nnum num ntotal total st n st n delete name delete num total 释放一个对象 学生人数减1 91 结果 name Wangnum 000001total 3name Yangnum 000002total 3 注意 a b c的total都是3 即说明静态数据成员只有一个拷贝 为所有对象共用 voidmain st na Wang 000001 st nb Yang 000002 st nc Tang 000003 a print b print 92 第四章类与对象 4 静态数据成员与非静态数据成员的区别 1 非静态数据成员与对象相关 每个对象拥有独立的拷贝 静态数据成员与类相关 2 非静态数据成员只有在定义了对象之后才分配存储空间 静态数据成员在定义对象之前就已存在 3 非静态数据成员的生存期局限在定义对象的块作用域内 静态数据成员从定义开始到整个程序结束 5 静态成员函数的声明classX static类型静态成员函数名 形参表 6 静态成员函数的定义 93 第四章类与对象 静态成员函数与一般成员函数的定义完全相同 7 静态成员函数的调用格式1 类名 静态成员函数名 实参表 格式2 对象名 静态成员函数名 实参表 说明 1 静态成员函数是属于整个类的 它只能用来访问类的静态数据成员 2 同普通成员函数一样 静态成员函数也可在类内或类外定义 还可以定义成内联函数 3 静态成员函数定义时 其类型前面不能冠以static 4 静态成员函数可在定义类的任何对象之前被调用 非静态成员函数只能在定义对象之后通过对象调用 例4 16静态成员函数的应用 94 include includeclassst n char name num 学生姓名 学号staticinttotal 声明静态数据成员 学生人数public st n char char st n voidprint staticintgetTotal 声明静态成员函数 用来访问静态数据成员 intst n total 0 定义静态数据成员 初值0st n st n char n1 char n2 name newchar strlen n1 1 num newchar strlen n2 1 strcpy name n1 strcpy num n2 total 创建一个对象 学生人数加1 95 intst n getTotal 定义静态成员函数 returntotal 访问静态数据成员 voidst n print cout name name endl num num endl st n st n delete name delete num total 释放一个对象 学生人数减1 96 voidmain st na Wang 000001 st nb Yang 000002 st nc Tang 000003 a print cout total a getTotal endl b print cout total st n getTotal endl 结果 name Wangnum 000001total 3name Yangnum 000002total 3 97 第四章类与对象 4 7对象成员 1 何为对象成员数据成员的类型可以是整数 如intID 可以是指针 如char name等等 用一个类的对象作为另一个类的数据成员 这就是对象成员 2 好处丰富类的数据成员的表示 通过简单的类来定义复杂的类 实现代码的重用和共享 提高代码的可维护性 3 类对象成员形式classX 类名1对象成员名1 类名n对象成员名n 98 第四章类与对象 为便于描述 假设对象成员所属的类为A类 使用对象成员的类为B类 4 需要解决的问题 1 对象成员中的数据成员如何初始化 即构造函数如何写 在B类的构造函数中调用A类的构造函数来完成对对象成员中的数据成员的初始化 具体操作是在B类的构造函数中采用初始化列表的方式实现 2 对象成员中的成员函数如何调用 由 对象成员 成员函数 的形式完成调用 见如下例子 99 例4 17对象成员的应用 saveasscore hclassscore public 公有成员score float float float 构造函数score 缺省构造函数voidprint 打印成绩voidmodify float float float 修改成绩private 私有成员floatcomputer floatenglish floatmathematics 类结束标志 100 saveasscore cpp include score h includescore score floatc floate floatm 构造函数 computer c english e mathematics m score score computer english mathematics 0 无参构造函数voidscore modify floatc floate floatm computer c english e mathematics m voidscore print cout nscorecomputer computer nscoreenglish english nscoremathematics mathematics 101 定义类student score的对象作为其成员 saveasstudent h include score h 包含类scoreclassstudent public student int char float float float student 析构函数voidmodify int char float float float voidprint private intnumber 学号char name 姓名scores 成绩 是类score的对象 包含了scor

温馨提示

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

评论

0/150

提交评论