C++类的定义及其应用Word文档下载推荐.docx
- 文档编号:7959270
- 上传时间:2023-05-09
- 格式:DOCX
- 页数:21
- 大小:32.48KB
C++类的定义及其应用Word文档下载推荐.docx
《C++类的定义及其应用Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《C++类的定义及其应用Word文档下载推荐.docx(21页珍藏版)》请在冰点文库上搜索。
等包含命令时,可以使用usingnamespacestd;
命令翻开命名空间的限制.
E1_3
在VisualC++6.0编译环境中要使用一系列的I/O流类,就应该包含头文
件iostream.
⑵对象:
现实世界中的一切事物都是对象,对象可以是有形的,比方一间房问,一本书籍;
也可以是无形的,比方一个方案.对象可以是一个简洁的个体,比方一个学生;
也可以是由其它对象组合而成,比方一个公司有多个部门,每个部门乂由许多员工组成.
对类似的对象进行抽象,找出共同的届性就可以构成一种类形.
作为了面向对象的程序设计语言,C+M持“抽象〞.将抽象后的数据和函数“封
装〞在一起,就构成了C++勺“类〞.
⑶在面向过程的结构化程序设计中,程序的模块是由函数构成的.函数将逻辑上相关的语句和数据封装,用丁完成特定的功能.
在面向对象的程序设计中,程序的模块是由类构成的.类是对逻辑上相关的函数和数据的封装,是对问题的抽象描述.即将抽象得到的数据和函数有机的结合成一个整体,形成“类〞.其中的数据和函数都是类的成员.
类实际上相当丁一种用户自定义的类型,在定义一个类时要说明其数据和操作内容.
就象一个钟表,是“钟类〞的一个实例.它调节时间的装置是“外部接口同时,其内部的各个部件有机的进行工作,但是外界是不能干预的.
类的定义:
class类名称标识符(
类的特性:
封装、继承和多态
成员列表:
包含数据成员和成员函数的定义及存取控制类别.
};
类成员函数的实现
其中:
数据成员(届性),成员函数(行为了方法).
成员的存取控制类别:
private:
除了友元函数外,类的外界(对象)不能直接访问该类别成员,只有类定义中的成员函数或数据成员可以访问该类别成员.在类定义中private:
假设紧接著类名称,该关键字可以省略.
※很好的表达了类的封装特性.
public:
类的外界(对象)可以直接访问该类别成员,并且可以通过该类别成员访问private类别的类成员.
※定义了类的外部接口.
protected:
在涉及类继承时使用.
※类成员的存取控制类别定义没有先后顺序.
作用域说明符:
用丁说明类成员的回届.
类定义中的成员函数的定义在类定义中完成,而成员函数的实现通常是在类定义外完成的.所以,要使用作用域说明符来说明成员函数回届丁那一个
类.当然,类定义中的成员函数的实现也可以在类定义中完成,但是,这样的函数通常只包含简洁的顺序结构的语句(见内联函数).
类的使用:
定义类的对象(类的对象是类定义的实例).
类对象的建立(安排存储空间)需要构造,释放内存空间需要析构.
构造函数:
在创立对象时,利用特定值将对象初始化为了一个特定的状态.
构造函数在对象被创立时被自动调用,没有函数返回值.
在类的public成员中可以定义有多个参数数量及参数类型不同的构造函数,函数名称即为了类的名称.
YSC1-1、YSC1-2
构造函数执行步骤:
⑴根据初始化列表为了相应届性赋初值,如果成员为了对象,根据给定的初始值执行该对象的构造函数.
⑵执行构造函数的函数体语句.
YSC1-3YSC1-4
※假设在类的定义中没有定义构造函数,C+嘶译器将自动产生缺省的构造函
数.该函数无参,也不做任何实质性的工作.由于在对象被创立时自动调用构造函数是“例行公事〞.
析构函数:
用丁完成对象生存期结束前的一些活理工作.函数调用结束,对象在内存中所占内存空间被释放.
析构函数在对象的生存期即将结束时被自动调用,没有参数和函数返回值.
在类的public成员中可以定义一个(只能是一个)析构函数,函数名称为了在类的名称前加符号“~〞.
析构函数执行步骤:
假设程序中有多个类对象存在,对象析构时的顺序与构造的顺序相反.
YSC1-5
※假设在类的定义中没有定义析构函数,C++S译器将自动产生缺省的析构函
数.该函数无参,也不做任何实质性的工作.由于在对象被创立时自动调用析构函数同样是“例行公事〞.
※构造函数和析构函数无函数返回值,所以,该函数也无须定义函数类型.
※假设有动态安排内存的操作,定义构造函数和析构函数是十分必要的
还可以根据需要在类定义中定义拷贝构造函数和赋值函数.
拷贝构造函数:
特别的构造函数.
调用拷贝构造函数的情况:
⑴当用已经存在(构造完毕)的同类对象(初始值对象)的引用作为了参数,初始化构造新建立的对象时将调用拷贝构造函数.
函数是在构造新的对象时被调用执行的.函数的参数必须是同类对象的引用.
YSC1-6-1
YSC1-6-1程序中Ak(h);
语句调用A(constA&
a)(x=a.x+2;
y=a.y+4;
}函数的执行.const表示不能在函数语句中修改参数对象.
⑵如果函数的形参是类的对象,调用函数时,实参给形参参数传递赋值时将调用拷贝构造函数.
YSC1-6-2
⑶如果函数的返回值是类的对象,函数执行结束完成返回时将调用拷贝构造函数.
YSC1-6-3
YSC1-6-3程序中k对象是函数f()中的局部对象,函数f()执行结束就不存在了.编译系统会在主调函数的主函数中创立一个“临时无名对象〞,该临时对象的生存期只在调用语句的表达式h=f()中.执行returnk;
语句时,实际上是调用拷贝构造函数将k的值拷贝到临时对象中.函数f()执行结束时k对象释放(注意:
该对象要析构),但是,临时对象存在丁表达式h=f()中.计算完该表达式后,临时对象的工作也就完成而被释放了(注意:
该临时对象要析构).
⑷如果被拷贝的对象本体与参数对象的实体是一致的,那么无须定义拷贝构造函数,利用编译系统生成的缺省函数即可完成拷贝构造(浅拷贝).而被拷贝的对
象本体与参数对象的实体是不一致的,那么必须定义拷贝构造函数(深拷贝).
YSC1-7
YSC1-7程序中类定义中包含指针成员,申请动态内存空间,应在类中定义拷贝构造函数,在拷贝数据时将调用拷贝构造函数.这样可以预防产生“两次析构〞同一数据的错误产生.
※假设在类的定义中没有定义拷贝构造函数,C++S译器将自动产生缺省的拷贝
构造函数.该函数的功能是把初始值对象的每个数据成员的值等值赋值给新建立对象的数据成员.
类的组合:
类的组合描述的是类定义中嵌有其它类的对象作为了成员的情况,这是一种包含和被包含的关系.当创立类的对象时,如果该类具有内嵌对象成员,那么各内嵌对象将首先被自动创立.因此,在创立对象(组合类的对象)时,既要对本类的根本类型的数据进行初始化,乂要对内嵌对象的成员进行初始化.
在创立一个组合类的对象时,不仅其自身的构造函数将被调用,而且,还将调用其内嵌对象的构造函数,构造函数的调用顺序是:
⑴根据组合类中内嵌对象的书写顺序调用内嵌对象的构造函数.
⑵执行组合类构造函数的函数体.
如果定义组合类对象时未指定对象的初值,那么默认形式(无形参)的构造函数被调用,此时内嵌对象的默认形式构造函数也被调用.析构函数的调用执行顺序与构造的调用执行顺序相反.
如果定义组合类时未定义拷贝构造函数,那么C+嘶译器将自动产生缺省的拷贝构造函数,且调用缺省的拷贝构造函数时系统将调用内嵌对象成员的拷贝构造函数.
如果定义组合类时定义拷贝构造函数,那么需要为了内嵌对象成员的拷贝构造函数传递参数.
YSC1-8
赋值函数:
用已经存在(构造完毕)的同类对象的引用作为了参数,向已经存在(构造完毕)的同类对象做赋值操作时将调用赋值函数.
该函数实际上是对“=〞的操作符重载,尤其当类中含有指针成员时,必须对对象的赋值操作定义赋值函数.
YSC1-3YSC1-10
YSC1-9程序中h=g;
语句调用A&
operator=(constA&
a)函数的执行.const
表小不能在函数语句中修改参数对象.
h对象是调用该函数的对象,g对象是该函数的参数对象.该函数作为了类的成员函数形式定义,必须有一个返回值.由丁,函数定义时将函数定义为了对象的引用(&
),所以,语句return*this;
返回h对象的引用值.
该函数中的this指针是个隐含丁每个成员函数中的特别指针,他指向正在被该函数操作的对象,在YSC1-9程序中为了对象h0
YSC1-11
YSC1-11程序中的语句if(this==&
s)return*this;
是在检查是否为了自赋值.语句delete[]p;
先释放指针变量p原指向的内存单元,然后在后续语句中重新申请安排内存.
※假设在类的定义中没有定义赋值函数,C+嘶译器将自动产生缺省的赋值函
数.该函数的功能是把表达式赋值号右侧对象的每个数据成员的值等值赋值给赋值号左侧对象的数据成员(这样做要慎重!
).
内联函数:
类定义中成员函数可以定义成内联函数,方法是在函数定义前加关键字
inline.
在普通函数调用时将程序转到被调函数的内存地址中,结束后再返回,这样做存在有时间及空间上的开销.
函数内联是将函数体在编译时来替换调用函数的语句,也就没有“转来转去〞的开销了,但是这样做增加了程序目标代码量.因此,内联函数是为了解决函数调用的效率问题.
在内联函数中不允许包含循环和开关语句,内联函数定义必须出现在第一次被调用之前.通常内联函数中只包含简洁的顺序结构语句.并且,编译系统将成员函数的实现在类定义中完成的函数也看成是内联函数.
静态数据成员:
某一类的所有对象具有相同的届性(届性的数量、名称及数据类型相同),但各个对象的具体届性值各不相同,这样的届性可以称为了对象届性(实例届性).这样的届性(数据成员)默认的存储类型届丁动态型.
类届性:
是描述类的所有对象共同特征的数据项,对丁任何对象实例,该届性值是相同的,即该届性值为了整个类共有,不届丁任何一个具体的队象.
可以用static关键字声明成员为了静态数据成员.静态数据成员届丁类,被类对象所共有,该类对象均可以访问该静态数据成员.
※静态成员的赋初值在类外进行,只能通过类名对其进行访问.
静态成员函数:
用static关键字声明的成员函数也届丁整个类,由同类的所有对象共有.对丁public权限的静态成员函数可以通过类名或对象名来调用.
YSC2
补充:
E3_1、E3_2、E3_3
思考题:
输入一组整数,找出并显示最大值、最小值;
显示类加和及平均值.
友元函数:
由丁类的成员函数是以对象为了中心的,必须通过对象才能调用相应的成员函
数,并且,某类对象的成员函数不能直接访问其它类对象的private成员.但是,
将类A的成员函数声明为了类B的友元函数,类A的对象就可以通过该友元函数直接访问类B的对象的private成员了.
如上所述,对丁类B而言,它的友元函数不是其成员函数,但是,它的友元函数需要在其类定义中说明,并在函数说明语句前加关键字friend.
YSC3-1
YSC3-1程序中Teacher类的成员函数voids_g(Student&
s)在Student类中被定义成该类的友元函数:
friendvoidTeacher:
s_g(Student&
s);
如果类A是类B的友元类,那么类A的所有成员函数都是类B的友元函数,都可以访问类B的private成员.
YSC3-2
YSC3-2程序中Teacher类在Student类中被定义成该类的友元类:
friendclassTeacher;
Teacher类的成员函数均是Student类的友元函数.
友元的特点:
⑴友元关系不能传递,即如果类B是类A的友元,类C是类B的友元,但没有其它声明,那么类A和类C之间没有友元关系.
⑵友元关系是单向的,即如果类B是类A的友元,那么类B的成员函数可以访问类A的private成员,但反之不可以.
⑶友元关系不能被继承,即如果类B是类A的友元,那么类B的派生类并不会
自动成为了类A的友元.
指针:
可以定义指向类的成员及指向类对象的指针变量.
对象指针变量:
用丁存放对象指针的指针变量.
对象指针变量在使用之前要先定义,并应进行初始化赋值,让该指针变量明
确指向一个已经定义过的对象.通过对象的指针变量可以访问到对象的public成
员.
this指针变量:
是隐含丁每个类的成员函数中的特别指针变量.
this指针变量用丁指向正在被成员函数操作的对象.
指向类的非静态成员的指针变量:
指向对象成员的指针变量在使用之前要先定义,说明该指针变量可以指向对员所在类的的成员,并应进行初始化赋值,让该指针变量明确指向类的哪一个成员.通过该指针变量只能访问到对象的public成员.
由丁类的定义中只是确定了各个数据成员的数据类型及在类中的相对位置,并不为了数据成员安排具体的内存空间.因此,在定义了指向对象成员的指针变量后,只是说明了被赋值的指针变量是专门用丁指向哪个数据成员的,同时在该指针变量中存放该数据成员在类中的相对位置.在定义了类的对象后,只要将对象的指针与指针变量中存放的相对位置结合起来就可以访问对象的数据成员了.
指向类的静态成员的指针变量:
对类的静态成员的访问是不用依赖丁对象的,因此,可以用普通的指针变量来指向和访问静态成员.
YSC4
YSC4®
序中的intA:
*p=&
A:
c;
语句定义指针变量p指向类A的数据成员c.
序中的int(A:
*q)(int)=&
f;
语句定义指针变量q指向类A的成
员函数f.
序中的A*k仁&
x;
语句定义指针变量k指向类A的对象x.
由于程序运行时应该通过定义对象来访问类的成员,所以,如上所用指针变
量,需要先定义类A的对象,然后通过对象来使用上述指针变量.
如YSC4S序中的语句
x.*p=6;
使得对象x的成员c的值为了6.
k1->
*p=9;
使得对象x的成员c的值为了9.
k2->
c=1;
使得对象y的成员c的值为了1.
cout<
<
"
(k1->
*q)(5)="
*q)(5)<
endl;
输出对象x的成员函数f的返
回值.
继承与派生:
继承机制是利用已有的数据类型来定义新的数据类型,使得新定义的数据类型不仅拥有自定义的成员,同时还“有条件〞的拥有“旧有〞的成员,从而实现代码的重用和扩充.
假设类B继承类A,那么称类B是类A的派生类(子类),类A是类B的基类(父类).可以在基类中抽象定义各种方法,而在派生类中增加扩充和改良的方法和届性.
继承的种类:
一个派生类可以有一个或多个基类.只有一个基类时称为了单继承;
有多个基类时称为了多继承.
继承的特点:
⑴继承关系可以是多级的,如类Y继承类X,类Z继承类Y.
⑵不允许循环继承.
⑶继承是单向的.
继承的结果:
派生类对象包含两局部数据:
继承自基类的数据局部(除了构造函数和析构函数以外的所有成员,实现了代码的重用.)和派生类自身定义的数据局部(实现了代码的扩充).
另外,还可以在派生类中定义和基类中同名的成员,从而到达对基类成员的隐藏控制.
YSC5-1、YSC5-2
YSC5-2程序中的类B继承类A,B类对象g可以使用的方法除了类B中定义的函数f2以外,还可以使用类A中定义的函数fl.
YSC5-2程序中并未定义A类对象.如果定义A类对象,该对象所占内存单元为了一个整型数据单元(以VisualC+珈译系统为了例是4个字节);
由于类B继承类A,所以,B类对象g所占内存单元中分为了两个局部:
继承自基类的数据局部和派生类自身定义的数据局部(以VisualC++编译系统为了例是8个字节).
派生类的构造函数:
基类的构造函数不能被继承.在派生类中,如果对派生类新增的成员进行初始化,就必须要为了派生类编写新的构造函数.派生类的构造函数需要以恰当的初值数据作为了参数,其中一些参数要用丁对派生类自身新增加的成员进行初始化,另一些参数那么要传递给基类的构造函数,用丁初始化相应的成员.
汪息:
如果基类定义了带有形参表的构造函数时,派生类就应当定义构造函数.
派生类对象的构造顺序:
先构造继承数据局部,再构造自身数据局部.
第⑴步骤:
首先根据派生类对象有无参数调用派生类相应的构造函数.
第⑵步骤:
a)假设该构造函数有初始化数据列表
1假设该初始化数据列表中对继承数据局部和自身数据局部的初始化内容都存在,那么不管书写顺序怎样,先调用基类的相应构造函数构造继承数据局部,然后再依次初始化自身各个局部的数据.
YSC5-3-1
2假设该初始化数据列表中只有继承数据局部的初始化内容,那么对继承数据局部调用基类中相应的构造函数完成初始化.
YSC5-3-2
3假设该初始化数据列表中只有自身数据局部的初始化内容,那么先调用基类中的无参构造函数完成继承数据局部的初始化,再接着完成自身数据局部的初始化.
YSC5-3-3
b)假设该构造函数没有初始化数据列表
无条件调用基类中的无参构造函数完成继承数据局部的初始化
YSC5-3-4
第⑶步骤:
执行派生类对象构造函数的函数体语句.
派生类的析构函数:
基类的析构函数函数不能被继承.
派生类对象的析构:
先析构自身数据局部,再析构继承数据局部.
派生类的拷贝构造函数:
如果派生类未定义拷贝构造函数,那么c++S译器将自动产生缺省的拷贝构造函数,且调用缺省的拷贝构造函数时系统将调用基类的拷贝构造函数.
如果派生类定义拷贝构造函数,那么需要为了基类相应的拷贝构造函数传递参数.
单继承的继承方式:
关丁protected成员的用法:
在单类的情况下,protected成员的用法与
private成员的用法一致.
YSC5-4
⑴公有基类(classB:
publicA)
基类的public(除了构造函数和析构函数)成员和protected成员等价丁派生类的public成员.
注意:
①基类对象不能访问基类自身的private和protected成员.
②基类的public和protected成员对丁派生类可见.但是,基类的protected成员只能被派生类的public成员使用,而不能直接被派生类的对象使用;
基类的public成员能直接被派生类的对象使用.
通常,基类可以将不允许基类自身对象使用,但是,却可以让派生类可以使用的方法设计成protected成员,如界面程序.
YSC5-5
类型兼容规那么:
在需要基类对象的任何地方,都可以使用公有派生类对象来替代.
⑴派生类对象可以给基类对象赋值.
⑵派生类对象可以初始化基类的引用.
⑶派生类对象的地址可以赋值给指向基类的指针.
※在替代之后,派生类对象就可以作为了基类的对象使用,但是,只能使用从基类继承的成员.
YSC5-6YSC5-7YSC5-8
⑵私有基类(classB:
privateA)
基类的public成员和protected成员等价丁派生类的private成员.
基类的public和protected成员对丁派生类可见.但是,基类的public和protected成员只能被派生类的成员函数使用,而不能直接被派生类的对象使用.
YSC5-9
⑶保护基类(classB:
protectedA)
基类的public成员和protected成员等价丁派生类的protected成员.
如果是classB:
protectedA,那么此现象等同丁private继承,但是,假设classB:
publicA,然后,classC:
protectedB,贝Uprotected继承才与private继承有所区别.
YSC5-10
※从类的继承角度看,派生类的对象可以有条件的使用基类中的方法和自身所包含的继承数据局部的届性.
※从类的封装角度看,不允许派生类的对象不受限制的使用继承的数据局部,即便是使用,也应该使用基类中定义的方法来使用继承数据局部.
派生类成员的隐藏规那么:
在类的派生层次结构中,基类的成员和派生类的新增成员都具有类的作用域,二者的范围不同.如果派生类声明了一个和基类成员同名的新成员,派生类的新成员就隐藏了基类的同名成员,直接使用成员名只能访问到派生类的成员.再直接说,如果派生类声明了一个和基类成员函数同名的新成员函数,即使函数的参数不同,从基类继承的同名函数的所有重载形式也会被隐藏.
YSC5-11
输入学生的考试成绩,显示学位平均分.要求:
学生姓名应该去除无效字符;
学生考试成绩应该进行合理性验证.
多态:
针对类而言,多态是指同样的类成员函数调用针对不同的对象有不同的实现,即实际调用的是不同的函数.
面向对象的多态分为了:
重载多态:
比方普通函数以及类成员函数的重载,运算符重载.
强制多态:
比方在运算时的强制类型转换.
以上两种多态也被称为了专用多态
包含多态:
比方定义在不同类中的同名成员函数的多态行为了,是通过虚函数来实现的.
参数多态:
与类模板相关.
以上两种多态也被称为了通用多态
虚函数:
表达了类的多态特性,并且引入了动态联编的概念,是动态绑定的根底.
当被调函数中的形参为了基类的引用对象或对象的指针时才考虑虚函数使用的现象.继承是虚函数使用的前提,虚函数的使用表达了类的多态特性.
YSC6_V0
YSC6_V(g序中GS^public继承S类,但同时这两个类均需要定义对象完成相应的工作,其中的score函数在两个类中的定义很相似但有区另[J,因此funl函数和fun2函数从形式上看非常相似,能否只写一个这样的函数?
YSC6_V1
YSC6_V促序中fun函数的定义假设写成voidfun(S&
a)时编译是正确的,main主函数中函数调用fun(a);
语句的执行是正确的.但是,函数调用fun(b);
语句的执行结果是错误的(程序执行了但结果是错误的).YS68_V1程序中fun函数的定义假设写成voidfun(GS&
a)时编译出现错误,由于,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 定义 及其 应用