《第2章类与对象PPT讲稿.ppt》由会员分享,可在线阅读,更多相关《第2章类与对象PPT讲稿.ppt(38页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第2章类与对象1第1页,共38页,编辑于2022年,星期一C语言语言基本数据类型:整型、浮点型、字符型。基本数据类型:整型、浮点型、字符型。构造类型:枚举、结构体构造类型:枚举、结构体C+把结构体扩展把结构体扩展自定义数据类型自定义数据类型类的概念2第2页,共38页,编辑于2022年,星期一C+的类从的类从C的结构体发展而来。的结构体发展而来。在在C+中,我们可以自己来定义一个类型,并且使用时就像使用基本数中,我们可以自己来定义一个类型,并且使用时就像使用基本数据类型那样简单。据类型那样简单。自自定定义义类类型型的的使使用用,就就像像使使用用基基本本数数据据类类型型那那样样简简单单,对对应应的
2、的实实体体就就称称之之为为对对象象。因因此此,编编程程的的意意义义就就是是算算法法在在对对象象之之间间穿穿梭梭,或或曰曰针针对对对象的算法设计对象的算法设计。所以其相应的编程就是对象化的编程了。所以其相应的编程就是对象化的编程了。3第3页,共38页,编辑于2022年,星期一一个类的框架结构 类的声明即类的定义类的声明即类的定义,声明一个类的语法与结构,声明一个类的语法与结构的声明类似:的声明类似:class /class是声明类的关键字是声明类的关键字 private:public:;4第4页,共38页,编辑于2022年,星期一 如何定义C+的类以时钟类为例子以时钟类为例子5第5页,共38页,
3、编辑于2022年,星期一类类和和对对象象的的关关系系相相当当于于普普通通数数据据类类型型与与其其变变量量的的关关系。系。声明一个声明一个类类:定义了一种新的:定义了一种新的数据类型数据类型;对象对象说明:创建这种说明:创建这种数据类型的物理实体数据类型的物理实体。由由同同一一个个类类创创建建的的各各个个对对象象具具有有完完全全相相同同的的数数据据结结构,但它们的数据值在使用过程中可能各不相同。构,但它们的数据值在使用过程中可能各不相同。一一旦旦创创建建了了一一个个类类的的对对象象,程程序序就就可可以以用用圆圆点点运运算算符符“.”来引用类的公有成员,其一般形式为来引用类的公有成员,其一般形式为
4、 或或 对象对象6第6页,共38页,编辑于2022年,星期一 类类的的成成员员函函数数用用于于对对数数据据成成员员进进行行处处理理,又又称称为为“方方法法”,程程序序中中通通过过类类的的成成员员函函数数来来访访问问其其内内部部的的数数据据成成员员。一一般般类类中中成成员员函函数数的的原原型型声声明明写写在在类类定定义义体体内内,用用以以说说明明该该成成员员函函数数的的形形式式参参数数和和返返回回值值类类型型,而而成成员员函函数数的的定定义义体体一一般般写写在在类类定定义义之之外外。通通常常采采用用下面的形式定义成员函数:下面的形式定义成员函数::()7第7页,共38页,编辑于2022年,星期一
5、例例如如,用用前前面面定定义义的的Clock类类声声明明一一个个Clock的的对对象象c1,通过对象,通过对象c1完成对成员函数完成对成员函数 showTime()的调用:的调用:Clock c1(12,30,0);c1.showTime();注注意意:只只有有用用public定定义义的的公公有有成成员员才才能能使使用用圆圆点点操操作作符符访访问问,对对象象中中的的私私有有成成员员是是类类中中隐隐藏藏的的数数据据,不不允允许许在在类类外外的的程程序序中中被被直直接接访访问问,只只能能通通过过该该类类的的公公有成员函数来访问它们。有成员函数来访问它们。8第8页,共38页,编辑于2022年,星期一
6、如何设计一个类1抽抽象象:抽抽取取本本质质特特性性(共共性性),加加以以简简单单描描述述例例如如用用C+语言将圆形语言将圆形(circle)抽象如下:抽象如下:数据抽象:数据抽象:对象对象属性属性和和状态状态的描述的描述 double x,y,r;行为抽象:行为抽象:数据所需要的数据所需要的操作操作 setx();sety();setr();draw();抽象是面向对象方法的核心抽象是面向对象方法的核心。9第9页,共38页,编辑于2022年,星期一2封装:封装:内部细节对外隐藏,通过接口进行控制内部细节对外隐藏,通过接口进行控制使程序使程序中各部分之间的相互影响达到最小;中各部分之间的相互影响
7、达到最小;提高程序的安全性;提高程序的安全性;简化代码的编写工作;简化代码的编写工作;对象中的对象中的数据数据(即(即属性属性)、)、操作代码操作代码(即(即行为行为)称)称为对象的为对象的成员成员。私有成员:对象中被隐藏的部分;私有成员:对象中被隐藏的部分;公有成员:对象与外界的接口。公有成员:对象与外界的接口。封装的封装的两个目标两个目标:1.数据和行为的包装;数据和行为的包装;2.信息隐藏。信息隐藏。10第10页,共38页,编辑于2022年,星期一实验定义一个定义一个Point类,包含类,包含x、y坐标,包含一下功能:坐标,包含一下功能:1)设置)设置x坐标坐标2)设置)设置y坐标坐标3
8、)得到)得到x坐标坐标4)得到)得到y坐标坐标11第11页,共38页,编辑于2022年,星期一构造函数构造函数:在类中声明的一种在类中声明的一种特殊的成员函数特殊的成员函数;作用:作用:将将对象初始化对象初始化为一个特定的状态为一个特定的状态。构构造造函函数数的的名名字字与与它它所所属属的的类类名名相相同同,被被声声明明为为公有函数公有函数,没有返回值没有返回值,在创建对象时被,在创建对象时被自动调用自动调用。构造函数可以构造函数可以访问类的所有数据成员访问类的所有数据成员,可以带有,可以带有参数表参数表,可以带,可以带默认的形参值默认的形参值。构造函数也可以。构造函数也可以重载重载,以提供初
9、始化类对象的不同方法。以提供初始化类对象的不同方法。构造函数和析构函数12第12页,共38页,编辑于2022年,星期一例如,前面定义的例如,前面定义的Clock类类的构造函数为的构造函数为Clock(int h,int m,int s)hour=h;minute=m;second=s;每每个个类类都都必必须须有有构构造造函函数数,若若类类定定义义时时没没有有定定义义任任何何构构造造函函数数,编编译译器器会会自自动动生生成成一一个个不不带带参参数数的的缺缺省省构造函数,其形式如下:构造函数,其形式如下::()/13第13页,共38页,编辑于2022年,星期一作用:对象失效时,进行系统放弃对象内存
10、之前的清作用:对象失效时,进行系统放弃对象内存之前的清 理工作,使内存可用来保存新的数据。析构理工作,使内存可用来保存新的数据。析构 函数本身并不实际删除对象。函数本身并不实际删除对象。例:例:rectangle()函数体函数体 析构函数14第14页,共38页,编辑于2022年,星期一定义拷贝构造函数的一般形式为:定义拷贝构造函数的一般形式为:class class_nameprivate:public:class_name(形式参数表形式参数表)/构造函数构造函数 函数体函数体 class_name(class_name&ob_name)/拷贝构造函数拷贝构造函数 函数体函数体 拷贝构造函数
11、调用场合:拷贝构造函数调用场合:1.用类的一个对象去初始化该类的另一个对象;用类的一个对象去初始化该类的另一个对象;2.函数的形参是类的对象;函数的形参是类的对象;3.函数的返回值是类的对象。函数的返回值是类的对象。拷贝构造函数15第15页,共38页,编辑于2022年,星期一默认拷贝构造函数默认拷贝构造函数只是把作为参数传递的对象的每默认拷贝构造函数只是把作为参数传递的对象的每一个成员变量复制到新对象的成员变量中去。我一个成员变量复制到新对象的成员变量中去。我们把这种拷贝叫浅拷贝。们把这种拷贝叫浅拷贝。大部分情况下这样是可行的。但当成员变量有指向大部分情况下这样是可行的。但当成员变量有指向自由
12、存储区中的对象的指针时,就会有问题:自由存储区中的对象的指针时,就会有问题:16第16页,共38页,编辑于2022年,星期一浅拷贝把一个对象的成员精确地复制到另外一个对象中,浅拷贝把一个对象的成员精确地复制到另外一个对象中,两个对象中的指针最后均指向同一内存。两个对象中的指针最后均指向同一内存。当任何一个Cat类超出作用域时,这样做会导致灾难性的后果。如果原来的Cat析构函数释放了这段内存而新的Cat类仍然指向这段内存,就会产生一个无效指针。浅拷贝17第17页,共38页,编辑于2022年,星期一解决的办法就是创建你自己的复制构造函数并根据需要分配内存。然后将原来的值复制到新的内存中。这叫深拷贝
13、。18第18页,共38页,编辑于2022年,星期一深拷贝19第19页,共38页,编辑于2022年,星期一结论类成员有指针并且需要动态分配内存的类类成员有指针并且需要动态分配内存的类三剑客:拷贝构造函数、赋值操作符重载、析构函数三剑客:拷贝构造函数、赋值操作符重载、析构函数 20第20页,共38页,编辑于2022年,星期一练习在刚才在刚才Point类里,实现构造函数、拷贝构造类里,实现构造函数、拷贝构造函数和析构函数。并在函数和析构函数。并在main()函数里生成一函数里生成一个个Point对象,观察构造函数和析构函数的调对象,观察构造函数和析构函数的调用顺序。用顺序。21第21页,共38页,编
14、辑于2022年,星期一#include class point private:int x,y;public:point(int xx=0,int yy=0)/定义构造函数定义构造函数 x=xx;y=yy;cout 构造函数被调用构造函数被调用 endl;point(point&p);/声明拷贝构造函数声明拷贝构造函数 point()/定义析构函数定义析构函数 cout 析构函数被调用析构函数被调用endl;int getx()return x;int gety()return y;22第22页,共38页,编辑于2022年,星期一point:point(point&p)/定义拷贝构造函数定义拷
15、贝构造函数 x=p.x;y=p.y;cout 拷贝构造函数被调用拷贝构造函数被调用 endl;void f(point p)/函数的形参是类的对象函数的形参是类的对象 coutp.getx()p.gety()endl;point g()point a(7,33);return a;/函数的返回值是类的对象函数的返回值是类的对象23第23页,共38页,编辑于2022年,星期一void main()point a(15,22);/构造函数被调用构造函数被调用 point b(a);/拷贝构造函数被调用拷贝构造函数被调用 coutb.get()b.gety()endl;f(b);/拷贝构造函数被调用
16、,析构函数被调用拷贝构造函数被调用,析构函数被调用 b=g();/构造函数和拷贝构造函数各被调用一次,构造函数和拷贝构造函数各被调用一次,/析构函数被调用两次析构函数被调用两次 coutb.getx()b.gety()endl;/析构函数被调用两次析构函数被调用两次24第24页,共38页,编辑于2022年,星期一一个初始化的小问题一个初始化的小问题class manydatambrs public:/缺省构造函数缺省构造函数 manydatambrs();/拷贝构造函数拷贝构造函数 manydatambrs(const manydatambrs&x);private:int a,b,c,d,e
17、,f,g,h;double i,j,k,l,m;假如想把所有的假如想把所有的int初始化为初始化为1而所有的而所有的double初始化为初始化为0,最好的办法是什么?最好的办法是什么?25第25页,共38页,编辑于2022年,星期一class manydatambrs public:/缺省构造函数缺省构造函数 manydatambrs();/拷贝构造函数拷贝构造函数 manydatambrs(const manydatambrs&x);private:int a,b,c,d,e,f,g,h;double i,j,k,l,m;void init();/用于初始化数据成员用于初始化数据成员;voi
18、d manydatambrs:init()a=b=c=d=e=f=g=h=1;i=j=k=l=m=0;manydatambrs:manydatambrs()init();.26第26页,共38页,编辑于2022年,星期一 将将一一个个已已定定义义的的类类的的对对象象作作为为另另一一个个类类的的数数据据成成员。例如:员。例如:Class A ;Class B private:A a;public:;类的组合类的组合27第27页,共38页,编辑于2022年,星期一:(形参表形参表):对象成员对象成员1(形参表形参表),对象成员,对象成员2(形参表形参表),类的初始化程序体类的初始化程序体 其中,构
19、造函数冒号后的部分其中,构造函数冒号后的部分“对象成员对象成员1(形参表形参表),对象成,对象成员员2(形参表形参表),”称作称作成员初始化列表成员初始化列表,用于完成对组合类中所,用于完成对组合类中所包含的对象成员的初始化,该表列出了初始化各对象成员所使用包含的对象成员的初始化,该表列出了初始化各对象成员所使用的构造函数。的构造函数。注意:注意:各成员对象的各成员对象的构造函数的调用次序与构造函数的调用次序与这些成员对象在这些成员对象在类中的类中的声明次序一致声明次序一致,而与,而与成员初始化列表成员初始化列表中给出的次序无关。中给出的次序无关。组合类构造函数定义的一般形式:28第28页,共
20、38页,编辑于2022年,星期一组合类中构造函数调用次序组合类中构造函数调用次序#include#include class point/声明声明point类类 private:int x,y;public:point(int i=0,int j=0)/定义构造函数定义构造函数 x=i;y=j;coutpoint构造函数被调用构造函数被调用endl;point(point&p);/声明拷贝构造函数声明拷贝构造函数29第29页,共38页,编辑于2022年,星期一#include class point private:int x,y;public:point(int xx=0,int yy=0)
21、/定义构造函数定义构造函数 x=xx;y=yy;cout 构造函数被调用构造函数被调用 endl;point(point&p);/声明拷贝构造函数声明拷贝构造函数 point()/定义析构函数定义析构函数 cout 析构函数被调用析构函数被调用endl;int getx()return x;int gety()return y;30第30页,共38页,编辑于2022年,星期一 point:point(point&p)/定义拷贝构造函数定义拷贝构造函数 x=p.x;y=p.y;coutpoint拷贝构造函数被调用拷贝构造函数被调用endl;31第31页,共38页,编辑于2022年,星期一clas
22、s distance/声明声明distance类(组合类)类(组合类)private:point p1,p2;double dist;public:distance(point xp1,point xp2);/声明组合类构造函数声明组合类构造函数 distance()coutdistance析构函数被调用析构函数被调用endl;double getDist()return dist;32第32页,共38页,编辑于2022年,星期一/定义组合类构造函数定义组合类构造函数:distance:distance(point xp1,point xp2):p1(xp1),p2(xp2)coutdista
23、nce构造函数被调用构造函数被调用endl;double x=double(p1.getx()-p2.getx();double y=double(p1.gety()-p2.gety();dist=sqrt(x*x+y*y);void main()point myp1(1,1),myp2(4,5);/point构造函数被调用构造函数被调用2次次 distance myd(myp1,myp2);/point拷贝构造函数被调用拷贝构造函数被调用4次次 /distance构造函数被调用构造函数被调用1次次 coutthe distance is:myd.getDist()yabbaDabbaDo();/错误:错误:Fred类的对象在定类的对象在定 /义之前被使用义之前被使用 private:Fred*x;/正确,经过前向引用声明,正确,经过前向引用声明,;/可以声明可以声明Fred类对象指针类对象指针class Fred public:void yabbaDabbaDo();private:Barney*y;37第37页,共38页,编辑于2022年,星期一应该记住:当你使用前向引用声明时,你只能使用被应该记住:当你使用前向引用声明时,你只能使用被声明的符号,而不能涉及类的任何细节。声明的符号,而不能涉及类的任何细节。38第38页,共38页,编辑于2022年,星期一
限制150内