面向对象程序设计语言C++-课模板cs课件

上传人:痛*** 文档编号:241846416 上传时间:2024-07-30 格式:PPT 页数:100 大小:461.54KB
返回 下载 相关 举报
面向对象程序设计语言C++-课模板cs课件_第1页
第1页 / 共100页
面向对象程序设计语言C++-课模板cs课件_第2页
第2页 / 共100页
面向对象程序设计语言C++-课模板cs课件_第3页
第3页 / 共100页
点击查看更多>>
资源描述
面向面向对象程序象程序设计语言言C+-精品精品课模板模板csC+与与C最最大大的的不不同同在在于于C+增增加加了了面面向向对对象象的的概概念念。C+允允许许用用户户定定义义新新的的抽抽象象数数据据类类型型类类类类型型,它它将将一一组组数数据据和和与与这这些些数数据据相相关关的的操操作作封封装装在在一一起起,实实现现了了面面向向对对象象技技术术中中的的核核心概念心概念数据封装数据封装。2024/7/302抽象是对具体对象(问题)进行概括,抽象是对具体对象(问题)进行概括,抽出这一类对象的抽出这一类对象的公共性质公共性质并加以描述并加以描述的过程。的过程。先注意问题的本质及描述,其次是实现过先注意问题的本质及描述,其次是实现过程或细节。程或细节。数据抽象:描述某类对象共有的属性或状数据抽象:描述某类对象共有的属性或状态。态。行为抽象:描述某类对象共有的行为特征行为抽象:描述某类对象共有的行为特征或具有的功能。或具有的功能。抽象抽象2024/7/303抽象实例抽象实例:时钟:时钟数据抽象:数据抽象:具有表明当前时间的具有表明当前时间的时、分、秒时、分、秒行为抽象:行为抽象:具有具有设置时间设置时间和和显示时间显示时间两个最两个最基本的功能基本的功能2024/7/304抽象实例抽象实例:人人数据抽象:数据抽象:姓名、年龄、性别等姓名、年龄、性别等行为抽象:行为抽象:生物属性:吃饭、穿衣、睡觉、行走等行为生物属性:吃饭、穿衣、睡觉、行走等行为社会属性:工作、学习等行为社会属性:工作、学习等行为2024/7/305在研究问题时,侧重点不同,可能会产生在研究问题时,侧重点不同,可能会产生不同的抽象结果;解决同一问题时要求不不同的抽象结果;解决同一问题时要求不同,也会产生不同的抽象结果。例如:同,也会产生不同的抽象结果。例如:如果开发一个人事管理软件,那么关心的是员工的如果开发一个人事管理软件,那么关心的是员工的姓名、性别、工龄、工资、工作部门等相关信息。姓名、性别、工龄、工资、工作部门等相关信息。如果开发学籍管理软件,那么关心的是学生的姓名、如果开发学籍管理软件,那么关心的是学生的姓名、性别、年龄、籍贯、所在学院等相关信息。性别、年龄、籍贯、所在学院等相关信息。因此,抽象是相对,而非绝对的。因此,抽象是相对,而非绝对的。2024/7/306如何实现抽象?如何实现抽象?抽象定义了一个事物的本质特征,那么抽象定义了一个事物的本质特征,那么从软件设计的角度又如何对抽象出来的从软件设计的角度又如何对抽象出来的结果进行描述呢?结果进行描述呢?封装可以实现抽象。封装可以实现抽象。封装就是将封装就是将数据和操作这些数据的函数数据和操作这些数据的函数进行有机地结合。进行有机地结合。C+的解决方案:的解决方案:用类来实现封装机制用类来实现封装机制2024/7/307定义和使用类的基本过程定义和使用类的基本过程第一步:进行抽象第一步:进行抽象第二步:定义类第二步:定义类第三步:实现类第三步:实现类第四步:使用类第四步:使用类2024/7/308类的定义:类的成员构成类的定义:类的成员构成class ClassName数据成员数据成员函数成员函数成员;类是一种抽象数据类型,声明形式如下:类是一种抽象数据类型,声明形式如下:关键字关键字class用于声用于声明一个类类型明一个类类型用于表达数据抽象用于表达数据抽象用于表达行为抽象用于表达行为抽象2024/7/309类定义举例:时钟类类定义举例:时钟类class Clockint Hour,Minute,Second;void SetTime(int h,int m,int s);void ShowTime();2024/7/3010类成员的访问控制类成员的访问控制什么是什么是“类内类内”和和“类外类外”在类定义之内称为类内在类定义之内称为类内在类定义之外称为类外在类定义之外称为类外数据封装的目的就是数据封装的目的就是信息隐蔽信息隐蔽。为了达到信。为了达到信息隐蔽,在息隐蔽,在C+类中,并非所有的成员都是类中,并非所有的成员都是对外可见的(或者说,是类外可以访问的)。对外可见的(或者说,是类外可以访问的)。通过设置成员的通过设置成员的访问控制属性访问控制属性来实现对类成来实现对类成员的访问控制。这些控制属性有:员的访问控制。这些控制属性有:public、protected、private2024/7/3011类的定义:对成员的访问控制类的定义:对成员的访问控制class ClassNamepublic:公有成员公有成员protected:保护成员保护成员private:私有成员私有成员;2024/7/3012公有成员公有成员在关键字在关键字public后面声明,它们是类与后面声明,它们是类与外部的接口,任何外部的接口,任何类内、类外类内、类外函数函数都可都可以访问公有数据和函数。以访问公有数据和函数。class Clockpublic:void SetTime(int h,int m,int s);/公有成员函数公有成员函数 void ShowTime();/公有成员函数公有成员函数;2024/7/3013私有成员私有成员在关键字在关键字private后面声明,后面声明,只允许本只允许本类中的函数(类中的函数(即类内函数即类内函数)访问,而类)访问,而类外的任何函数都不能访问。外的任何函数都不能访问。class Clockprivate:int Hour,Minute,Second;/私有数据成员私有数据成员;2024/7/3014保护成员保护成员在关键字在关键字protected后面声明后面声明的数据成的数据成员或成员函数。与员或成员函数。与private类似,其差别类似,其差别表现在继承与派生时对派生类的影响不表现在继承与派生时对派生类的影响不同,在第八章中再描述。同,在第八章中再描述。2024/7/3015类定义举例:时钟类类定义举例:时钟类class Clockpublic:void SetTime(int h,int m,int s);void ShowTime();private:int Hour,Minute,Second;2024/7/3016类的实现类的实现实现一个类,就是按照所设定的功能实现一个类,就是按照所设定的功能语义去实现类中的每一个成员函数。语义去实现类中的每一个成员函数。2024/7/3017class Clockprivate:int Hour,Minute,Second;public:void SetTime(int h,int m,int s)Hour=h;Minute=m;Second=s;void ShowTime()cout“Current Time:”coutHour“:”Minute“:”Second endl;在类内实现成员函数,编译器按在类内实现成员函数,编译器按内联函数处理内联函数处理在类内实现成员函数,编译器按在类内实现成员函数,编译器按内联函数处理内联函数处理2024/7/3018class Clockprivate:int Hour,Minute,Second;public:void SetTime(int h,int m,int s);/给出函数原型给出函数原型 void ShowTime();/给出函数原型给出函数原型;void Clock:SetTime(int h,int m,int s)Hour=h;Minute=m;Second=s;void Clock:ShowTime()cout“Current Time:”coutHour“:”Minute“:”Second 公有成员函数名公有成员函数名(形参列表形参列表);对象的指针对象的指针-公有数据成员公有数据成员2024/7/3021举例:一个比较完整的举例:一个比较完整的Clock类类/定义定义Clock类类class Clockprivate:int Hour,Minute,Second;public:void SetTime(int h,int m,int s);void addHour(int h);void addMinute(int m);void addSecond(int s);void ShowTime();2024/7/3022/实现实现Clock类中的成员函数类中的成员函数void Clock:SetTime(int h,int m,int s)Hour=h;Minute=m;Second=s;void Clock:addHour(int h)Hour+=h;void Clock:addMinute(int m)Minute+=m;void Clock:addSecond(int s)Second+=s;void Clock:ShowTime()cout“Current Time:”;coutHour“:”Minute“:”Secondendl;2024/7/3023/使用使用Clock类类void main()Clock clock_1,clock_2;clock_1.SetTime(9,5,25);clock_2.SetTime(15,16,45);clock_1.addHour(3);clock_2.addMinute(8);clock_1.ShowTime();clock_2.ShowTime();程序输出:程序输出:Current Time:12:5:25 Current Time:15:24:452024/7/3024总结:定义和使用类类型的过程总结:定义和使用类类型的过程抽象:抽象:对事物进行抽象对事物进行抽象定义类:定义类:根据抽象的结果定义类的特性根据抽象的结果定义类的特性实现类:实现类:实现类中成员函数的逻辑实现类中成员函数的逻辑使用类:使用类:在程序中定义类的实例,使用在程序中定义类的实例,使用类的公有成员。类的公有成员。2024/7/3025在在定定义义类类时时,把把可可以以被被外外部部访访问问的的成成员员说说明明为为public属属性性,作作为为外外部部访访问问类类中中成成员员的的接接口口。把把不不能能被被外外部部访访问问的的成成员员说说明明为为private或或protected属性。属性。私有成员私有成员公有成员公有成员类对外的接口类对外的接口保护成员保护成员2024/7/3026请思考以下情况请思考以下情况能调用下面语句吗?能调用下面语句吗?clock_1.Hour=21;如果将如果将ShowTime说明为说明为private属性,属性,还能调用如下语句吗?还能调用如下语句吗?clock_2.ShowTime();2024/7/3027练习一练习一设计一个三角形类设计一个三角形类CTriangle,该类满足下,该类满足下述要求:述要求:a)有一个成员函数)有一个成员函数SetEdge,用于设置三,用于设置三角形的边。角形的边。b)有一个成员函数)有一个成员函数GetArea,用于获得三,用于获得三角形的面积。角形的面积。c)有一个成员函数)有一个成员函数GetCircumference,用,用于获得三角形的周长。于获得三角形的周长。在在main函数中,实例化一个函数中,实例化一个Ctriangle类的类的对象,将三条边分别为对象,将三条边分别为3、4、5,然后将,然后将其面积和周长显示在屏幕上。其面积和周长显示在屏幕上。2024/7/3028备注:备注:1三角形面积的计算方式如下:三角形面积的计算方式如下:a、b、c分别为三条边,分别为三条边,S代表面积,代表面积,p=(a+b+c)/2,那么,那么S2=p(p-a)(p-b)(p-c)。2求开平方的库函数是求开平方的库函数是sqrt,需要包含,需要包含math.h头文件,使用方式的举例如下:头文件,使用方式的举例如下:int a,b;b=36;a=sqrt(b);那么那么a的值为的值为62024/7/3029练习二练习二Need To Do2024/7/3030几点说明几点说明在声明类时,具有不同访问属性的成员可以按任在声明类时,具有不同访问属性的成员可以按任意顺序出现。意顺序出现。class Clockprivate:int Hour,Minute,Second;public:void SetTime(int h,int m,int s);void ShowTime();protected:;2024/7/3031修饰访问属性关键字可以多次出现。修饰访问属性关键字可以多次出现。class Clockpublic:void SetTime(int h,int m,int s);private:int Hour,Minute,Second;public:void ShowTime();2024/7/3032一个成员只能具有一种访问属性,否则会出现歧异一个成员只能具有一种访问属性,否则会出现歧异。class Clockpublic:void SetTime(int h,int m,int s);void ShowTime();private:void ShowTime();int Hour,Minute,Second;2024/7/3033例子:简单例子:简单int数组类数组类/数组类的定义数组类的定义const int ARRAY_SIZE=4;class MyArrayint dataARRAY_SIZE;public:int getArraySize();int setVal(int pos,int val);int getMaxVal();int getMinVal();2024/7/3034/数组类的实现数组类的实现int MyArray:getArraySize()return ARRAY_SIZE;int MyArray:setVal(int pos,int val)if(posARRAY_SIZE)return-1;datapos=val;return 0;2024/7/3035/数组类的实现数组类的实现(续续)int MyArray:getMaxVal()int temp=data0;for(int i=1;itemp)temp=datai;return temp;int MyArray:getMinVal()int temp=data0;for(int i=1;iARRAY_SIZE;i+)if(dataitemp)temp=datai;return temp;2024/7/3036/数组类的使用数组类的使用int main()MyArray array;int i,size,v,max,min;size=array.getArraySize();coutplease input size numbers:endl;for(i=0;iv;array.setVal(i,v);max=array.getMaxVal();min=array.getMinVal();coutmax value is:maxendl;coutmin value is:minendl;return 0;2024/7/3037改造:为简单改造:为简单int数组类增加公用的私有函数数组类增加公用的私有函数/数组类的定义:增加公用的私有函数数组类的定义:增加公用的私有函数const int ARRAY_SIZE=4;class MyArrayint dataARRAY_SIZE;int getVal(int condition);public:int getArraySize();int setVal(int pos,int val);int getMaxVal();int getMinVal();2024/7/3038/数组类的实现:增加和调用公用的私有函数数组类的实现:增加和调用公用的私有函数int MyArray:getVal(int condition)int temp=data0;for(int i=1;itemp)temp=datai;elseif(datai SetTime(9,5,25);p-ShowTime();p-SetTime(10,3,28);p-ShowTime();2024/7/3041关键字关键字thisC+为为每每个个非非静静态态成成员员函函数数提提供供一一个个this指针。指针。this指指针针是是一一个个隐隐含含的的指指针针,它它指指向向了了正正在被成员函数操作的那个对象。在被成员函数操作的那个对象。this指指针针不不能能显显式式声声明明,它它只只是是非非静静态态成成员函数的一个形参。员函数的一个形参。2024/7/3042this指针举例指针举例class Counterint value;public:void setValue(int value)this-value=value;class Counterint value;public:void setValue(int v)value=v;void main()Counter obj1,obj2;obj1.setValue(1);obj2.setValue(2);2024/7/3043class Counterint value;public:void setValue(Counter*this,int v)this-value=v;class Counterint value;public:void setValue(int v)value=v;void main()Counter obj1,obj2;obj1.setValue(1);obj2.setValue(2);编译器做了特殊处理编译器做了特殊处理void main()Counter obj1,obj2;obj1.setValue(&obj1,1);obj2.setValue(&obj2,2);2024/7/3044构造函数和析构函数构造函数和析构函数类类的的数数据据成成员员是是不不能能在在定定义义时时直直接接初始化的,以初始化的,以Clock类为例:类为例:class Clockprivate:int Hour=0,Minute=0,Second=0;/错误错误;2024/7/3045当当Clock类类被被实实例例化化时时,如如何何初初始始化化对对象象的的状状 态态,即即 如如 何何 初初 始始 化化 Hour、Minute、Second三三个个成成员员呢呢?一一种种可可行行的的方方式式就就是是显式调用初始化函数。显式调用初始化函数。Clock clock1;clock1.SetTime(21,34,43);但是这种方式存在一些不好的情况:但是这种方式存在一些不好的情况:程程序序员员可可能能会会忘忘记记调调用用SetTime()函函数数,导导致对象没有被初始化。致对象没有被初始化。2024/7/3046构造函数构造函数实实际际上上,我我们们更更希希望望这这个个初初始始化化工工作作能能够够自自动动进进行行。类类的的构构造造函函数数提提供供了了这种这种自动化功能自动化功能。构造函数是类的一种特殊成员,构造函数是类的一种特殊成员,函数函数名和类名相同,没有名和类名相同,没有返回类型,返回类型,可以可以有参数。当创建类的一个新对象时,有参数。当创建类的一个新对象时,构造函数被构造函数被自动调用自动调用,完成对象的初,完成对象的初始化工作。始化工作。2024/7/3047例:为例:为Clock类添加构造函数类添加构造函数class Clockprivate:int Hour,Minute,Second;public:Clock(int h,int m,int s);2024/7/3048构造函数初始化数据成员的两种方式构造函数初始化数据成员的两种方式赋值语句的方式:赋值语句的方式:Clock(int h,int m,int s)Hour=h;Minute=m;Second=s;表达式表的方式:表达式表的方式:Clock(int h,int m,int s):Hour(h),Minute(m),Second(s)2024/7/3049如果构造函数带有参数,那么在创建对象如果构造函数带有参数,那么在创建对象时必须给出对应的实参。时必须给出对应的实参。如果构造函数仅有一个参数:如果构造函数仅有一个参数:className obj=parameter;如果构造函数有一个或多个参数:如果构造函数有一个或多个参数:className obj(parameter list);如果构造函数有参数,但是在创建对象时如果构造函数有参数,但是在创建对象时又不给出对应的实参,此时编译出错。又不给出对应的实参,此时编译出错。传给构造函数实参的两种方式传给构造函数实参的两种方式2024/7/3050void main()Counter counter1(8);Counter counter2=9;Clock clock1(3,5,1);Clock clock2();/错误错误class Counterprivate:int value;public:Counter(int v):value(v);举例举例class Clockprivate:int Hour,Minute,Second;public:Clock(int h,int m,int s);2024/7/3051重载构造函数重载构造函数一个类可以提供多个构造函数,但它们的一个类可以提供多个构造函数,但它们的参数表必须不同。重载的目的是为了参数表必须不同。重载的目的是为了满足满足不同的初始化需要不同的初始化需要。class Clockprivate:int Hour,Minute,Second;public:Clock(int h,int m,int s);Clock();Clock(char*timestr);void main()Clock clock1(23,12,0);Clock clock2();Clock clock3(“14:45:32”);2024/7/3052具有缺省参数的构造函数具有缺省参数的构造函数构构造造函函数数也也可可以以有有缺缺省省参参数数。如如果果在在类类外外实现该函数时,就不能再说明缺省值了。实现该函数时,就不能再说明缺省值了。class Clockprivate:int Hour,Minute,Second;public:Clock(int h=0,int m=0,int s=0);Clock(const char*timestr);请思考一下,这个类还能再有一个没有任何参数请思考一下,这个类还能再有一个没有任何参数请思考一下,这个类还能再有一个没有任何参数请思考一下,这个类还能再有一个没有任何参数的构造函数吗?即:的构造函数吗?即:的构造函数吗?即:的构造函数吗?即:Clock();Clock();2024/7/3053缺省的构造函数缺省的构造函数对对于于没没有有构构造造函函数数的的类类,编编译译器器将将会会自自动动为为它它生生成成一一个个没没有有参参数数的的构构造造函函数数,该函数该函数不做任何工作不做任何工作。class Clockprivate:int Hour,Minute,Second;2024/7/3054析构函数析构函数与与构构造造函函数数相相对对的的是是析析构构函函数数。C+通通过过析析构函数来处理对象被销毁时的清理工作。构函数来处理对象被销毁时的清理工作。析析构构函函数数没没有有返返回回类类型型,没没有有参参数数,函函数数名名是在类名前加是在类名前加“”。析析构构函函数数将将会会在在对对象象的的生生存存期期结结束束后后被被自自动动调用调用。如如果果没没有有进进行行显显式式说说明明,系系统统将将会会生生成成一一个个不做任何事的缺省的析构函数。不做任何事的缺省的析构函数。2024/7/3055举例:为举例:为Clock类添加析构函数类添加析构函数class Clockprivate:int Hour,Minute,Second;public:Clock(int h=12,int m=0,int s=0);Clock();Clock:Clock()cout“Clock obj destroyed!”endl;2024/7/3056void func()Clock obj1,obj2;void main()func();/输出:输出:Clock obj destroyed!Clock obj destroyed!2024/7/3057析构函数的典型用法析构函数的典型用法class MyStringprivate:int len;char*buf;public:MyString(int n);void copy(char*src);MyString:MyString(int n)len=n;buf=new charn;void MyString:copy(char*src)strcpy(buf,src);void func()MyString obj(64);obj.copy(“helloworld”);void main()func();!此此时时,obj的的buf所所指指向向的的内存空间没有释放内存空间没有释放2024/7/3058class MyStringprivate:int len;char*buf;public:MyString(int n);MyString();void copy(char*src);MyString:MyString(int n)len=n;buf=new charn;void MyString:copy(char*src)strcpy(buf,src);MyString:MyString()delete buf;void func()MyString obj(64);obj.copy(“helloworld”);void main()func();!当当obj对对象象被被释释放放时时,析析构构函函数数被被自自动动调调用用,buf所所指指向的内存空间被释放向的内存空间被释放2024/7/3059拷贝构造函数拷贝构造函数构构造造函函数数的的参参数数可可以以是是任任意意类类型型,如如果果将将与与自自己己同同类类的的对对象象的的引引用用作作为为参参数数时时,该构造函数就称为该构造函数就称为拷贝构造函数拷贝构造函数。拷贝构造函数的特点:拷贝构造函数的特点:首首先先,它它是是一一个个构构造造函函数数,当当创创建建对对象象时时系统会自动调用它。系统会自动调用它。其其次次,它它将将一一个个已已经经创创建建好好的的对对象象作作为为拷拷贝贝构构造造函函数数的的参参数数,并并根根据据需需要要将将该该对对象象中的数据成员逐一对应地赋值给新对象。中的数据成员逐一对应地赋值给新对象。2024/7/3060示例示例class Pointprivate:float x,y;public:Point(float a,float b)x=a;y=b;Point(Point&obj)x=obj.x;y=obj.y;void main()Point obj1(5,15);/调用调用Point(float,float)Point obj2(obj1);/调用调用Point(A&)Point obj3=obj2;/调用调用Point(A&)2024/7/3061缺省的拷贝构造函数的应用缺省的拷贝构造函数的应用如如果果一一个个类类没没有有定定义义拷拷贝贝构构造造函函数数,那那么么C+编编译译器器会会为为该该类类产产生生一一个个缺缺省省的的拷拷贝贝构构造造函函数数。缺缺省省的的拷拷贝贝构构造造函函数数使使用用位位拷拷贝贝的的方方法法来来完完成成对对象象到到对对象象的的复复制制。也也就就是是说说,将将第第一一个个对对象象中中的的数数据据成成员员的的值值原原封封不不动动拷拷贝到第二个对象的数据成员中。贝到第二个对象的数据成员中。a_obja_objb_objb_objBit CopyBit Copy2024/7/3062例:缺省的拷贝构造函数的应用例:缺省的拷贝构造函数的应用class Pointprivate:float x,y;public:Point(float a,float b)x=a;y=b;void main()Point obj1(5,15);/调用调用A(float,float)Point obj2(obj1);/调用缺省的拷贝构造函数调用缺省的拷贝构造函数Point obj3=obj2;/调用缺省的拷贝构造函数调用缺省的拷贝构造函数obj2是是obj1的精确拷贝,的精确拷贝,obj3是是obj2的精的精确拷贝确拷贝2024/7/3063缺省的拷贝构造函数的缺点缺省的拷贝构造函数的缺点在大多数情况下,缺省拷贝构造函在大多数情况下,缺省拷贝构造函数工作得很好,但在一些特殊的场数工作得很好,但在一些特殊的场合,它的表现将不尽人意。合,它的表现将不尽人意。2024/7/3064class MyStringprivate:int len;char*buf;public:MyString(int n);MyString();void copy(char*src);MyString:MyString(int n)len=n;buf=new charn;void MyString:copy(char*src)strcpy(buf,src);MyString:MyString()delete buf;void func()MyString obj1(64);obj1.copy(“helloworld”);MyString obj2=obj1;void main()func();!由由于于调调用用的的是是默默认认的的拷拷贝贝构构造造函函数数,因因此此obj1和和obj2中中的的buf指指向向同同一一内内存存空空间间,当当它它们们被被释释放放时时,该该内内存存空间将被释放两次。空间将被释放两次。2024/7/3065改进办法:增加拷贝构造函数改进办法:增加拷贝构造函数class MyStringpublic:MyString(int n);MyString(MyString&obj);MyString:MyString(MyString&obj)len=obj.len;buf=new char len;strcpy(buf,obj.buf);通过自定义拷贝构造函数,可以准确通过自定义拷贝构造函数,可以准确地复制数据,以免发生错误。地复制数据,以免发生错误。2024/7/3066拷贝构造函数起作用的地方拷贝构造函数起作用的地方拷拷贝贝构构造造函函数数除除了了在在创创建建新新对对象象时时被调用外,还在以下情况被调用:被调用外,还在以下情况被调用:对象作为函数参数对象作为函数参数函数返回对象函数返回对象2024/7/3067举例举例class Counterprivate:int value;public:Counter(int v)value=v;void add(int v)value+=v;void show()coutvalueendl;Counter func(Counter obj)obj.add(6);return obj;void main()Counter b1=5;Counter b2=func(b1);b1.show();b2.show();输出:输出:5 112024/7/3068调用调用func(b1)时调用默认的拷贝构造函数时调用默认的拷贝构造函数调用调用return obj时调用默认的拷贝构造函数时调用默认的拷贝构造函数将将func()返返回回值值赋赋给给b2时时调调用用默默认认的的拷拷贝贝构构造函数造函数5b111temp11b25(11)objfunc(b1)return objb2=func(b1)2024/7/3069对象数组对象数组与与任任何何其其它它数数据据类类型型一一样样,可可以以创创建建一个类的对象数组。例如:一个类的对象数组。例如:Clock clocks10;通通过过下下标标访访问问数数组组中中的的对对象象,进进而而访访问该对象的公有成员,例如:问该对象的公有成员,例如:clocks3.ShowTime();2024/7/3070举例举例class Pointpublic:float x,y;Point()x=0;y=0;Point(float a)x=a;y=0;Point(float a,float b)x=a;y=b;void show()coutx“:”yendl;void main()Point array3;array1.x=5;array1.y=6;array1.show();输出:输出:5:62024/7/3071对象数组的初始化对象数组的初始化对对象象数数组组的的初初始始化化过过程程,实实际际上上就就是是调调用用构构造造函函数数对对每每一一个个数数组组元元素素进行初始化的过程。进行初始化的过程。如如果果在在声声明明数数组组时时给给出出每每一一个个数数组组元元素素的的初初始始值值,在在初初始始化化过过程程中中就就会调用会调用最匹配最匹配的构造函数。的构造函数。2024/7/3072class Pointpublic:Point()x=0;y=0;Point(float a)x=a;y=0;Point(float a,float b)x=a;y=b;void main()Point array3=Point(3,4),5;举例:对象数组初始化举例:对象数组初始化初始化初始化array0时调用的是时调用的是Point(float,float)构造函数构造函数初始化初始化array1时调用的是时调用的是Point(float)构造函数构造函数初始化初始化array2时调用的是时调用的是Point()构造函数构造函数2024/7/3073对象指针的加减操作对象指针的加减操作class Counterprivate:int value;public:Counter(int v)value=v;void show()coutvalueshow();p+;p-show();p+;p-show();输出:输出:5 6 72024/7/3074类类型作参数类型的三种方式类类型作参数类型的三种方式对象本身作为参数对象本身作为参数由由于于C+采采用用传传值值的的方方式式传传递递参参数数,因因此此使使用用对对象象本本身身参参数数时时,形形参参是是实实参参的的一一个个拷拷贝贝。在在这这种种情情况况下下,最最好好显显式式地地为为类类定定义义一一个个拷拷贝贝构构造函数,以免出现不容易发现的错误。造函数,以免出现不容易发现的错误。2024/7/3075举例举例:对象本身做函数参数对象本身做函数参数class Counterprivate:int value;public:Counter(int v)value=v;void add(int v)value+=v;void show()coutvalueadd(6);输出:输出:5 112024/7/3078静态成员静态成员当当用用关关键键字字static说说明明一一个个类类成成员员时时,该成员称为静态成员。因此可以分为:该成员称为静态成员。因此可以分为:静态数据成员静态数据成员静态成员函数静态成员函数2024/7/3079静态数据成员静态数据成员class ABCD /声明静态数据成员声明静态数据成员static int s_value;int value;ABCD A,B,C,D;Object AObject AValueValueObject DObject DvaluevalueObject BObject Bvaluevalues_values_valueObject CObject Cvaluevalue类的所有对象共享静态数据成员,因此无论建立多类的所有对象共享静态数据成员,因此无论建立多少个该类的对象,静态数据成员只有一份拷贝。少个该类的对象,静态数据成员只有一份拷贝。静态数据成员属于类,而不属于具体的对象。静态数据成员属于类,而不属于具体的对象。2024/7/3080静态数据成员的定义和初始化静态数据成员的定义和初始化在在类类内内只只是是静静态态数数据据成成员员的的声声明明,但但是是静静态态数数据据成员必须在类外定义,格式如下:成员必须在类外定义,格式如下:类型类型 类名类名:静态数据成员静态数据成员int ABCD:s_value;在在定定义义静静态态数数据据成成员员的的时时候候可可以以对对其其进进行行初初始始化化,方式如下:方式如下:类型类型 类名类名:静态数据成员静态数据成员int ABCD:s_value=6;2024/7/3081静态数据成员的使用静态数据成员的使用静态数据成员也有静态数据成员也有public和和private之分,由之分,由于静态数据成员是属于类的,因此:于静态数据成员是属于类的,因此:在类外,按如下形式访问在类外,按如下形式访问public静态数据成员:静态数据成员:类名类名:静态数据成员静态数据成员ABCD:s_value+;在类内,可以直接访问所有属性的静态数据成员在类内,可以直接访问所有属性的静态数据成员特别地,当类对象不存在时,也可以访问类特别地,当类对象不存在时,也可以访问类的静态数据成员。的静态数据成员。2024/7/3082例例1:静态数据成员的基本用法:静态数据成员的基本用法class counterstatic int count;/声明声明 public:void setcount(int num)count=num;void showcount()coutcount“;/定义定义int counter:count=0;void main()counter a,b;a.showcount();b.showcount();a.setcount(34);a.showcount();b.showcount();/输出:输出:0 0 34 342024/7/3083静态成员函数静态成员函数静态成员函数的定义静态成员函数的定义class ABCDpublic:static void show_staticvalue();静静态态成成员员函函数数只只属属于于一一个个类类,它它没没有有this指针。指针。静静态态成成员员函函数数也也可可以以声声明明为为public或或private属性。属性。2024/7/3084请思考请思考能能将将构构造造函函数数声声明明为为非非public属属性性吗吗?如果能,将会出现什么情况?如果能,将会出现什么情况?class Clockprivate:int Hour,Minute,Second;Clock(int h,int m,int s);void main()Clock aclock(1,2,3);编译出错,因为构造函数编译出错,因为构造函数是是private属性属性2024/7/3085举例:静态成员的应用举例:静态成员的应用如果有一个类如果有一个类MyClass,如何设计才能保,如何设计才能保证在程序运行中该类只能有一个实例?证在程序运行中该类只能有一个实例?利用静态成员可以解决该问题。利用静态成员可以解决该问题。class MyClassprivate:static MyClass*instance;MyClass()public:static MyClass*getInstance()if(instance=NULL)instance=new MyClass();return instance;MyClass*MyClass:instance=NULL;void main()MyClass*obj;obj=MyClass:getInstance();将将构构造造函函数数声声明明为为非非public属属性性,可以控制对象的生成!可以控制对象的生成!2024/7/3086友元关系友元关系封装的目的就是为了实现信息隐蔽。封装的目的就是为了实现信息隐蔽。一一个个对对象象的的私私有有成成员员只只能能被被自自己己的的成成员员访访问问到到。当当类类外外的的对对象象或或函函数数要要访访问问这这个个类类的的私私有有成成员员时时,只只能能通通过过该该类类提提供供的的公公有有成员成员间接地进行。间接地进行。出出于于效效率率(而而非非技技术术上上必必须须)的的考考虑虑,C+提提供供了了友友元元机机制制来来打打破破私私有有化化的的界界限限,即即一个类的友元可以访问到该类的私有成员。一个类的友元可以访问到该类的私有成员。2024/7/3087友元函数友元函数问题的提出问题的提出Point类代表类代表“点点”,考虑如下需求:,考虑如下需求:需要一个函数来计算任意两点间的距离,需要一个函数来计算任意两点间的距离,那么这个函数该如何设计呢?那么这个函数该如何设计呢?class Pointfloat x,y;public:Point(float xx=0,float yy=0)x=xx;y=yy;float GetX()return x;float GetY()return y;2024/7/3088解决方案解决方案1将计算两点距离的函数设计为类外的普通函数将计算两点距离的函数设计为类外的普通函数float Distance(Point a,Point b)float x1,x2,y1,y2,dx,dy;x1=a.GetX();y1=a.GetY();x2=b.GetX();y2=b.GetY();dx=x1-x2;dy=y1-y2;return sqrt(dx*dx+dy*dy);void main()Point p1(3.0,5.0),Point p2(4.0,6.0);float d=Distance(p1,p2);coutThe distance is ;coutdendl;/输出:输出:The distance is 1.14212024/7/3089这种方案的缺点:这种方案的缺点:因为类外函数是不能直接访问类中的私有成员的,因为类外函数是不能直接访问类中的私有成员的,因此该函数必须调用因此该函数必须调用GetX和和GetY公有成员函数先公有成员函数先获取获取“点点”的坐标,然后再计算两点距离,这种的坐标,然后再计算两点距离,这种方式是不太方便的。方式是不太方便的。另一种方案就是将计算两点距离的函数设计成另一种方案就是将计算两点距离的函数设计成为为Point类的成员函数。虽然从语法的角度来类的成员函数。虽然从语法的角度来看这不难实现,但是理解起来却有问题:看这不难实现,但是理解起来却有问题:距离反映的是两点之间的关系,它既不属于每一距离反映的是两点之间的关系,它既不属于每一个单独的点,也不属于整个个单独的点,也不属于整个Point类。类。2024/7/3090解决方案解决方案2:设计为友元函数:设计为友元函数将一个函数声明为一个类的友元函数时,将一个函数声明为一个类的友元函数时,该函数就具有以下特点:该函数就具有以下特点:该类函数可以直接访问私有成员。该类函数可以直接访问私有成员。友元函数不属于任何类,因此友元函数没有友元函数不属于任何类,因此友元函数没有this指针。指针。友元函数访问非静态成员的方式与静态成员函友元函数访问非静态成员的方式与静态成员函数是一样的。数是一样的。友元函数的声明可以放在类内的任何位置。友元函数的声明可以放在类内的任何位置。和普通函数一样,可直接调用友元函数。和普通函数一样,可直接调用友元函数。2024/7/3091float Distance(Point a,Point b)float dx,dy;dx=a.x-b.x;dy=a.y-b.y;return sqrt(dx*dx+dy*dy);void main()Point p1(3.0,5.0);Point p2(4.0,6.0);float d=Distance(p1,p2);coutThe distance is ;coutdendl;/输出:输出:The distance is 1.1421class Pointfriend float Distance(Point a,Point b);2024/7/3092友元类友元类除除了了将将一一个个普普通通函函数数声声明明为为一一个个类类的的友友元元函函数数外外,也也可可以以将将一一个个类类Y声声明明为为另另一一个个类类X的的友友元元类类,那那么么,类类Y中中的的所所有有成成员员函函数数都都成成为为类类X的的友友元元函函数数,都都能能直直接接访访问问类类X中所有的成员。中所有的成员。2024/7/3093举例举例class Y;/向前说明向前说明class Xint x;friend class Y;public:void show()coutx;class Y public:void SetX(X&obj,int v)obj.x=v;void main()X xobj;Y yobj;yobj.SetX(xobj,5);xobj.show();/输出:输出:52024/7/3094将成员函数说明为另一个类的友元函数将成员函数说明为另一个类的友元函数class X;/向前说明向前说明class Y public:void SetX(X&obj,int v);void func(X&obj);class Xfriend void Y:SetX(X&obj,int v);void Y:SetX(X&obj,int v)obj.x=v;2024/7/3095对友元关系的总结对友元关系的总结友元具有如下的性质:友元具有如下的性质:类的友元可以直接访问它的所有成员。类的友元可以直接访问它的所有成员。友元的声明必须放在类的内部,但放在哪个友元的声明必须放在类的内部,但放在哪个段没有区别。段没有区别。友元关系不具备对称性,即友元关系不具备对称性,即X是是Y的友元,的友元,但但Y不一定是不一定是X的友元。的友元。友元关系不具备传递性,即友元关系不具备传递性,即X是是Y的友元,的友元,Y是是Z的友元,但的友元,但X不一定是不一定是Z的友元。的友元。2024/7/3096类的组合类的组合一一个个类类的的对对象象作作为为另另一一个个类类的的成成员员,这这体体现现的的是是整整体体和和部部分分的的关关系系,即即对对象象的的包包含含关关系系,这个作为成员的对象被称为子对象。这个作为成员的对象被称为子对象。2024/7/3097举例:举例:Circle类的实现类的实现class Pointfloat x,y;public:Point(float xx,float yy)x=xx;y=yy;float GetX()return x;float GetY()return y;void moveto(float xx,float yy)x=xx;y=yy;2024/7/3098class CirclePoint center;float radius;public:Circle(float x,float y,float r):center(x,y)radius=r;void moveto(float xx,float yy)center.moveto(xx,yy);void main()Circle acircle(0,0,5);acircle.moveto(5,8);若子对象对应的类的构造函数有参数,那若子对象对应的类的构造函数有参数,那么包含该子对象的类必须使用表达式么包含该子对象的类必须使用表达式的方式先初始化子对象。的方式先初始化子对象。2024/7/3099谢谢
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!