C++面向对象程序设计.ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《C++面向对象程序设计.ppt》由用户(晟晟文业)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 面向 对象 程序设计
- 资源描述:
-
1、C+面向对象程序设计2.1 2.1 类和对象类和对象2.1.1 2.1.1 类的定义类的定义C+中定义类的一般格式如下:class private:public:protected:;2.1.1 2.1.1 类的定义类的定义当类的成员函数的函数体在类的外部定义时,必须由作用域运算符“:”来通知编译系统该函数所属的类。例如:class CMeterpublic:double m_nPercent;/声明一个公有数据成员void StepIt();/声明一个公有成员函数void SetPos(int nPos);/声明一个公有成员函数int GetPos()return m_nPos;/声明一个公
2、有成员函数并定义private:int m_nPos;/声明一个私有数据成员;/注意分号不能省略void CMeter:StepIt()m_nPos+;void CMeter:SetPos(int nPos)m_nPos=nPos;2.1.2 2.1.2 对象的定义对象的定义与结构类型一样,它也有三种定义方式:声明之后定义、声明之时定义和一次性定义。但由于“类”比任何数据类型都要复杂得多,为了提高程序的可读性,真正将“类”当成一个密闭、“封装”的盒子(接口),在程序中应尽量在对象的声明之后定义方式,并按下列格式进行:一个对象的成员就是该对象的类所定义的数据成员(成员变量)和成员函数。访问对象的
3、成员变量和成员函数和访问变量和函数的方法是一样的,只不过要在成员前面加上对象名和成员运算符“.”,其表示方式如下:.()例如:myMeter.m_nPercent,myMeter.SetPos(2),Meters0.StepIt();2.1.2 2.1.2 对象的定义对象的定义若对象是一个指针,则对象的成员访问形式如下:-()“-”是一个表示成员的运算符,它与“.”运算符的区别是:“-”用来表示指向对象的指针的成员,而“.”用来表示一般对象的成员。2.1.3 2.1.3 类作用域和成员访问权限类作用域和成员访问权限1 1类名的作用域类名的作用域如果在类声明之前就需要使用该类名定义对象,则必须用
4、下列格式在使用前进行提前声明(注意,类的这种形式的声明可以在相同作用域中出现多次):class;例如:class COne;class COne;/将类COne提前声明class COne;class COne;/可以声明多次class CTwo/private:COne a;/数据成员a是已定义的COne类对象;class COne/;2.1.3 2.1.3 类作用域和成员访问权限类作用域和成员访问权限2 2类中成员的可见性类中成员的可见性(1)在类中使用成员时,成员声明的前后不会影响该成员在类中的使用,这是类作用域的特殊性。例如:class Avoid f1()f2()f2();/调用类中
5、的成员函数f2coutaendl;/使用类中的成员变量avoid f2()int a;2.1.3 2.1.3 类作用域和成员访问权限类作用域和成员访问权限(2)由于类的成员函数可以在类体外定义,因而此时由“类名:”指定开始一直到函数体最后一个花括号为止的范围也是该类作用域的范围。例如:class Avoid f1();/;void A A:f1()/则从A:开始一直到f1函数体最后一个花括号为止的范围都是属于类A的作用域。(3)在同一个类的作用域中,不管成员具有怎样的访问权限,都可在类作用域中使用,而在类作用域外却不可使用。例如:class Apublic:int a;/;a=10;/错误,不
6、能在A作用域外直接使用类中的成员2.1.3 2.1.3 类作用域和成员访问权限类作用域和成员访问权限3 3类外对象成员的可见性类外对象成员的可见性对于访问权限public、private和protected来说,只有在子类中或用对象来访问成员时,它们才会起作用。在用类外对象来访问成员时,只能访问public成员,而对private和protected均不能访问。2.1.4 2.1.4 构造函数和析构函数构造函数和析构函数1 1构造函数构造函数C+规定,一个类的构造函数必须与相应的类同名,它可以带参数,也可以不带参数,与一般的成员函数定义相同,可以重载,也可以有默认的形参值。例如:class C
7、Meterpublic:CMeter(int nPos)/带参数的构造函数m_nPos=nPos;/这样若有:CMeter oMeter(10),oTick(20);2.1.4 2.1.4 构造函数和析构函数构造函数和析构函数2 2对构造函数的几点说明对构造函数的几点说明(1)构造函数的约定使系统在生成类的对象时自动调用。同时,指定对象括号里的参数就是构造函数的实参,例如,oMeter(10)就是oMeter.CMeter(10)。故当构造函数重载及设定构造函数默认形参值时,要避免出现二义。CPerson(char*str,float h=170,float w=130)/Astrcpy(na
8、me,str);height=h;weight=w;CPerson(char*str)/Bstrcpy(name,str);2.1.4 2.1.4 构造函数和析构函数构造函数和析构函数(2)定义的构造函数不能指定其返回值的类型,也不能指定为void 类型。事实上,由于构造函数主要用于对象数据成员的初始化,因而无须返回函数值,也就无须有返回类型。(3)若要用类定义对象,则构造函数必须是公有型成员函数,否则类无法实例化(即无法定义对象)。若类仅用于派生其他类,则构造函数可定义为保护型成员函数。2.1.4 2.1.4 构造函数和析构函数构造函数和析构函数3 3默认构造函数默认构造函数实际上,在类定义
9、时,如果没有定义任何构造函数,则编译自动为类隐式生成一个不带任何参数的默认构造函数,由于函数体是空块,因此默认构造函数不进行任何操作,仅仅为了满足对象创建时的语法需要。其形式如下:()例如,对于CMeter类来说,默认构造函数的形式如下:CMeter()/默认构造函数的形式 默认构造函数的目的是使下列对象定义形式合法:CMeter one;/one.CMeter();会自动调用默认构造函数2.1.4 2.1.4 构造函数和析构函数构造函数和析构函数4 4析构函数析构函数与构造函数相对应的是析构函数。析构函数析构函数是另一个特殊的C+成员函数,它只是在类名称前面加上一个“”符号(逻辑非),以示与
10、构造函数功能相反。每一个类只有一个析构函数,没有任何参数,也不返回任何值。例如:class CMeterpublic:/CMeter()CMeter()/析构函数析构函数 /析构函数只有在下列两种情况下才会被自动调用:(1)当对象定义在一个函数体中,该函数调用结束后,析构函数被自动调用。(2)用new为对象分配动态内存,当使用delete释放对象时,析构函数被自动调用。2.1.4 2.1.4 构造函数和析构函数构造函数和析构函数5 5应用示例应用示例类的构造函数和析构函数的一个典型应用是在构造函数中用new为指针成员开辟独立的动态内存空间,而在析构函数中用delete释放它们。【例Ex_Nam
11、e】使用构造函数和析构函数由于“CName one(p);”调用的是B重载构造函数,从而使得私有指针成员strName的指向等于p的指向。而p指向new开辟的内存空间,其内容为“DING”,一旦p指向的内存空间删除后,p的指向就变得不确定了,此时strName指向也不确定,所以此时运行结果为:葺葺葺葺?2.1.4 2.1.4 构造函数和析构函数构造函数和析构函数显然,输出的是一个无效的字符串。因此,为了保证类的封装性,类中的指针成员所指向的内存空间必须在类中自行独立开辟和释放。因此,类CName应改成下列代码。这样,主函数中的代码才会有正确的运行结果:DING2.1.5 2.1.5 对象赋值和
12、拷贝对象赋值和拷贝1 1赋值赋值在C+中,一个类的对象的初值设定可以有多种形式。例如,对于前面的类CName来说,则可有下列对象的定义方式:CName o1;/通过A显式默认构造函数设定初值CName o2(DING);/通过B重载构造函数设定初值等都是合法有效的。但是若有:o1=o2;/通过赋值语句设定初值C+还常用下列形式的初始化来将另一个对象作为对象的初值:()例如:CName o2(DING);/A:通过构造函数设定初值CName o3(o2);/B:通过指定对象设定初值2.1.5 2.1.5 对象赋值和拷贝对象赋值和拷贝每一个类总有一个默认拷贝构造函数,其目的是保证B语句中对象初始化
13、形式的合法性,其功能就等价于“CName o3=o2;”。但语句“CName o3(o2);”与语句“o1=o2;”一样,也会出现程序终止的情况,其原因和“o1=o2;”的原因一样。但是,若有类CData:class CDatapublic:CData(int data=0)m_nData=data;CData()int getData()return m_nData;private:intm_nData;2.1.5 2.1.5 对象赋值和拷贝对象赋值和拷贝则下列初始化形式却都是合法有效的:CData a(3);/通过重载构造函数设定初值CData b(a);/通过默认拷贝构造函数设定初值/等
14、价于 CData b=a;cout a.getData()endl;/输出 3cout b.getData()endl;/输出 32.1.5 2.1.5 对象赋值和拷贝对象赋值和拷贝2 2浅拷贝和深拷贝浅拷贝和深拷贝每一个C+类都有一个隐式的默认拷贝构造函数,其目的是保证对象初始化方式的合法性,其功能是将一个已定义的对象所在的内存空间的内容依次拷贝到被初始化对象的内存空间中。这种仅仅将内存空间的内容拷贝的方式称为浅拷贝浅拷贝。3 3深拷贝构造函数深拷贝构造函数拷贝构造函数是一种比较特殊的构造函数,除遵循构造函数的声明和实现规则外,还应按下列格式进行定义。(参数表)对于CName的拷贝构造函数,
15、可有下列合法的函数原型:CName(CName&x);/x为合法的对象标识符CName(const CName&x);CName(CName&x,);/“”表示还有其他参数CName(const CName&x,);2.1.5 2.1.5 对象赋值和拷贝对象赋值和拷贝【例Ex_CopyCon】使用拷贝构造函数程序运行结果如下:DINGDING YOU HE2.1.6 2.1.6 对象成员的初始化对象成员的初始化为提高对象初始化效率,增强程序的可读性,C+允许在构造函数的函数头后面跟一个由冒号“:”来引导的对象成员初始化列表,列表中包含类中对象成员或数据成员的拷贝初始化代码,各对象初始化之间用逗
16、号分隔,如下列格式::(形参表):对象1(参数表),对象2(参数表),对象n(参数表)对象成员初始化列表对象成员初始化列表2.1.6 2.1.6 对象成员的初始化对象成员的初始化先来看看第一种方式(函数构造方式),例如。但若使用第二种方式(对象成员列表方式),即使用由冒号“:”来引导的对象成员初始化列表的形式,如下面的代码:class CPoint/;class CRectpublic:CRect(int x1,int y1,int x2,int y2):m_ptLT(x1,y1),m_ptRB(x2,y2):m_ptLT(x1,y1),m_ptRB(x2,y2)private:CPoint
17、m_ptLT,m_ptRB;int main()CRect rc(10,100,80,250);return 0;2.2 2.2 数据共享和成员特性数据共享和成员特性1 1静态数据成员静态数据成员与静态变量相似,静态数据成员是静态存储(static)的,但定义一个静态数据成员与一般静态变量不一样,它必须按下列两步进行:(1)在类中使用关键字static声明静态数据成员。在类中声明静态数据成员,仅仅是说明了静态数据成员是类中的成员这个关系,即便用该类定义对象时,该静态数据成员也不会分配内存空间。(2)在类外为静态数据成员分配内存空间并初始化。类中数据成员的内存空间是在对象定义时来分配的,但静态数
18、据成员的内存空间为所有该类对象所共享,只能分配一次,因而不能通过定义类对象的方式来分配,必须在类的外部作实际定义才能为所有对象共享,其定义格式如下::=2.2 2.2 数据共享和成员特性数据共享和成员特性【例Ex_StaticData】静态数据成员的使用#include class CSumpublic:CSum(int a=0,int b=0)/A nSum+=a+b;int getSum()return nSum;void setSum(int sum)nSum=sum;private:static int nSum;/声明静态数据成员;int CSum:nSum=0;/静态数据成员的实际
19、定义和初始化int main()CSum one(10,2),two;coutone:sum=one.getSum()endl;couttwo:sum=two.getSum()endl;two.setSum(5);coutone:sum=one.getSum()endl;couttwo:sum=two.getSum()endl;return 0;2.2 2.2 数据共享和成员特性数据共享和成员特性程序运行结果如下:one:sum=12two:sum=12one:sum=5two:sum=52.2 2.2 数据共享和成员特性数据共享和成员特性2 2静态成员函数静态成员函数在类中,静态数据成员可以
20、被成员函数引用,也可以被静态成员函数所引用。但反过来,静态成员函数却不能直接引用类中说明的非静态成员。假如静态成员函数可以引用类中的非静态成员,例如:class CSumpublic:static void ChangeData(int data)static void ChangeData(int data)nSum=data;nSum=data;/错误错误:引用类中的非静态成员 public:int nSum;则当执行语句:CSum:ChangeData(5);/合法的静态成员引用2.2 2.2 数据共享和成员特性数据共享和成员特性【例Ex_StaticMember】静态成员的使用程序运行
21、结果如下:20,40,-50,7,13,-50,7,13,20,40,2.2.2 2.2.2 友元友元1 1友元概述友元概述类的私有型(private)数据成员和保护型(protected)数据成员只能在类中由该类的成员函数来访问,类的对象及外部函数只能访问类的公有型(public)成员函数,类的私有和保护型数据成员只能通过类的成员函数来访问,如图2.1(a)所示。但是,如果在类中用friend关键字声明一个函数,且该函数的形参中还有该类的对象形参,这个函数便可通过形参对象或通过在函数体中定义该类对象来访问该类的任何私有和保护型数据成员,如图2.1(b)所示。2.2.2 2.2.2 友元友元2
22、 2友元函数友元函数友元函数可分为友元外部函数和友元成员函数。当一个函数f是A类的友元,且f还是另一个类B的成员函数时,则这样的友元称为友元成员函数;若f不属于任何类的成员,则这样的友元称为友元外部函数。通常将友元外部函数直接简称为友元友元函数函数。友元函数在类中定义的格式如下:friend (形参表)2.2.2 2.2.2 友元友元3 3友元成员函数友元成员函数友元成员函数在类中定义的格式如下:friend :(形参表)【例Ex_FriendMemFun】使用友元成员函数程序运行结果如下:Point(10,20)Rect(0,0,100,80)Point(13,23)Rect(3,3,103
23、,83)2.2.2 2.2.2 友元友元4 4友元类友元类除一个类的成员函数可以声明成另一个类的友元外,也可以将一个类声明成另一个类的友元,称为友元类友元类。当一个类作为另一个类的友元时,就意味着这个类的所有成员函数都是另一个类的友元成员函数。友元类的声明比较简单,其格式如下:friend class;【例Ex_ClassFriend】使用友元类程序运行结果如下:Point(22,28)2.2.3 2.2.3 常类型常类型1 1常对象常对象常对象是指对象常量,定义格式如下:const 定义常对象时,修饰符const可以放在类名后面,也可以放在类名前面。例如:class COnepublic:C
24、One(int a,int b)x=a;y=b;/private:int x,y;const COne a(3,4);COne const b(5,6);2.2.3 2.2.3 常类型常类型2 2常指针和常引用常指针和常引用const的位置不同,其含义也不同,它有3种形式。第1种形式是将const放在指针变量的类型之前,表示声明一个指向常量的指针。此时,在程序中不能通过指针来改变它所指向的数据值,但可以改变指针本身的值。例如:int a=1,b=2;const int*p1=&a;/声明指向int型常量的指针p1,指针地址为a的地址*p1=2;/错误,不能更改指针所指向的数据值p1=&b;/正
25、确,指向常量的指针本身的值是可以改变的2.2.3 2.2.3 常类型常类型第2种形式是将const放在指针定义语句的指针名前,表示指针本身是一个常量,称为指针常量或常指针常指针。例如:int a=1,b=2;int*const p1=&a;/声明指向int型常量的指针p1,指针地址为a的地址int*const p2;/错误,在声明指针常量时,必须初始化*p1=2;/正确,指针所指向的数据值可以改变p1=&b;/错误,指针常量本身的值是不可改变的第3种形式是将const在上述两个地方都加,表示声明一个指向常量的指针常量,指针本身的值不可改变,而且它所指向的数据的值也不能通过指针改变。例如:int
展开阅读全文