构造函数与析构函数.ppt

上传人:牧羊曲112 文档编号:6301438 上传时间:2023-10-15 格式:PPT 页数:64 大小:304.49KB
返回 下载 相关 举报
构造函数与析构函数.ppt_第1页
第1页 / 共64页
构造函数与析构函数.ppt_第2页
第2页 / 共64页
构造函数与析构函数.ppt_第3页
第3页 / 共64页
构造函数与析构函数.ppt_第4页
第4页 / 共64页
构造函数与析构函数.ppt_第5页
第5页 / 共64页
点击查看更多>>
资源描述

《构造函数与析构函数.ppt》由会员分享,可在线阅读,更多相关《构造函数与析构函数.ppt(64页珍藏版)》请在三一办公上搜索。

1、1,第11章 构造函数与析构函数,教学主要内容类的构造函数析构函数静态成员友元重点与难点类与构造函数友元,2,第11章 构造函数与析构函数,教学目标(1)熟练掌握使用构造函数在创建对象时对其进行初始化(2)掌握使用析构函数在释放对象时清理现场(3)会使用友元访问类中的成员,3,第11章 构造函数与析构函数,11.1 构造函数与析构函数概述11.2 拷贝构造函数11.3 对象数组11.4 this指针11.5 静态成员11.6 友元,4,11.1.1 构造函数当建立一个对象时,对象的状态(数据成员的取值)是不确定的。常常需要初始化。C+中有一个称为构造函数的特殊成员函数,可自动进行对象的初始化。

2、相对于构造函数,一个称为析构函数的成员函数在对象撤消时自动执行清理任务。,11.1 构造函数和析构函数,5,构造函数,构造函数是一种特殊的成员函数,它的作用是在对象被创建时使用特定的值构造对象,或者说将对象初始化为一个特定的状态,给各成员数据赋初值。构造函数在对象创建时由系统自动调用。构造函数除具有一般成员函数的特性之外,还具有一些特殊的性质:(1)构造函数的名字必须与类名相同。(2)构造函数可以有任意类型的参数,但不能指定返回类型。它有隐含的返回值,该值由系统内部使用。(3)构造函数允许为内联函数、重载函数、带缺省形参值的函数。(4)构造函数被声明为公有函数,但它不能像其他成员函数那样被显式

3、地调用,它是在定义对象的同时被系统调用的。,6,构造函数的定义,在类定义时没有定义任何构造函数时,编译器会自动为这个类生成一个不带参数的缺省构造函数,其格式如下::()在程序中定义一个对象而没有进行初始化时,则编译器便按缺省构造函数来初始化该对象。只是这个构造函数的函数体是空的,也没有参数,不执行初始化操作。,7,构造函数的应用示例,【实例11-1-1】定义一个时钟类(包括:时、分、秒)及该类的对象,分别使用普通成员函数和构造函数初始化数据成员。,8,构造函数的应用示例,#include using namespace std;class Timepublic:Time()/定义构造成员函数,

4、函数名与类名相同hour=0;/利用构造函数对对象中的数据成员赋初值minute=0;sec=0;void set_time();/函数声明void show_time();/函数声明private:int hour;/私有数据成员int minute;int sec;,9,构造函数的应用示例,void Time:set_time()/定义成员函数,向数据成员赋值cinhour;cinminute;cinsec;void Time:show_time()/定义成员函数,输出数据成员的值 couthour:minute:secendl;void main()Time t1;/建立对象t1,同时调

5、用构造函数t1.Time()t1.set_time();/对t1的数据成员赋值t1.show_time();/显示t1的数据成员的值 Time t2;/建立对象t2,同时调用构造函数t2.Time()t2.show_time();/显示t2的数据成员的值,10,带参的构造函数的应用示例,【实例11-1-2】定义一个描述学生的类(包括:学号、姓名、年龄和班级号)及该类的对象,使用构造函数初始化数据成员。,11,/#include st.h#include#include#include class TStudent public:TStudent(char*sn,char*name,int ag

6、e,int cn);/说明构造函数 void ShowStudent();private:char sno5;char sname10;int sage;int cno;,构造函数的应用示例,12,/定义构造函数TStudent:TStudent(char*sn,char*name,int age,int cn)strcpy(sno,sn);strcpy(sname,name);sage=age;cno=cn;void TStudent:ShowStudent()coutsetw(6)snosetw(12)snamesetw(6)sagesetw(5)cnoendl;,构造函数的应用示例,13

7、,#include st.hvoid main()TStudent s1(001,张红,18,2);cout访问类成员n;coutsetw(6)snosetw(12)snamesetw(6)sagesetw(6)cnon;s1.ShowStudent();,构造函数的应用示例,14,【说明】(1)构造函数的名字TStudent与类名TStudent相同。(2)在建立对象s1时自动调用构造函数,给该对象中的成员赋初值(001,张红,18,2)。(3)由于构造函数不能显示调用,因此,实参是在定义对象时给出的。,构造函数的应用,15,在一个类中可以定义多个构造函数,以便对类对象提供不同的初始化的方法

8、,供用户选用。这些构造函数具有相同的名字,而参数的个数或参数的类型不相同。这称为构造函数的重载。,构造函数的重载,【实例11-1-3】定义一个描述学生的类(包括:学号、姓名、年龄和班级号)及该类的对象,使用重载、带缺省形参值的构造函数初始化数据成员。,16,构造函数的重载,#include#include#include class TStudent public:TStudent(char*sn,char*name,int age,int cn);TStudent(int cn=3);/指定缺省参数的值 void ShowStudent();private:char sno5;char sn

9、ame10;int sage,cno;,17,构造函数的重载,TStudent:TStudent(char*sn,char*name,int age,int cn)/构造函数定义 strcpy(sno,sn);strcpy(sname,name);sage=age;cno=cn;/重载、带缺省形参值构造函数的定义TStudent:TStudent(int cn)strcpy(sno,002);strcpy(sname,李力);sage=20;cno=cn;void TStudent:ShowStudent()coutsetw(6)snosetw(12)snamesetw(6)sagesetw(

10、5)cnoendl;,18,构造函数的重载,#include st.hvoid main()TStudent s1(001,张红,18,2),s2,s3(1);cout访问类成员n;coutsetw(6)snosetw(12)snamesetw(6)sagesetw(6)cnon;s1.ShowStudent();s2.ShowStudent();s3.ShowStudent();,19,构造函数的重载,【说明】(1)在执行语句TStudent s1(001,张红,18,2)时建立对象s1,并自动调用具有4个参数的构造函数TStudent(char*sn,char*name,int age,i

11、nt cn),给该对象中的成员赋初值(001,张红,18,2)。(2)在执行语句TStudent s2;时建立对象s2,并自动调用重载、并带缺省形参值的构造函数TStudent(3)。(3)在执行语句TStudent s3(1);时建立对象s3,并自动调用重载构造函数TStudent(1)。,20,11.1.2 用参数初始化表对数据成员初始化,前面介绍的是在构造函数的函数体内通过赋值语句对数据成员实现初始化。C+还提供另一种初始化数据成员的方法参数初始化表来实现对数据成员的初始化。这种方法不在函数体内对数据成员初始化,而是在函数首部实现。带有成员初始化表的构造函数的一般形式如下:类名:构造函数

12、名(参数表):(成员初始化表)/构造函数体成员初始化表的一般形式为:数据成员名1(初始值1),数据成员名2(初始值2),21,用参数初始化表对数据成员初始化实例,【实例11-1-4】定义一个描述学生的类(包括:学号、姓名、年龄和班级号),及该类的对象,使用成员初始化表初始化数据成员。,22,用参数初始化表对数据成员初始化实例,#include#include#include class TStudent public:TStudent(char*sn,char*name,int age,int cn);void ShowStudent();private:char sno5;char snam

13、e10;int sage;int cno;,23,用参数初始化表对数据成员初始化实例,/使用成员初始化表初始化数据成员TStudent:TStudent(char*sn,char*name,int age,int cn):sage(age),cno(cn)/初始化数据成员 strcpy(sno,sn);strcpy(sname,name);void TStudent:ShowStudent()coutsetw(6)snosetw(12)snamesetw(6)sagesetw(5)cnoendl;,24,用参数初始化表对数据成员初始化实例,void main()TStudent s1(001,

14、张红,20,2);cout访问类成员n;coutsetw(6)snosetw(12)snamesetw(6)sagesetw(6)cnon;s1.ShowStudent();,【说明】在执行语句TStudent s1(001,张红,18,2);时建立对象s1,并自动调用构造函数TStudent(char*sn,char*name,int age,int cn):sage(age),cno(cn),给该对象中的成员赋初值(001,张红,20,2)。,25,11.1.3 析构函数,析构函数也是一种特殊的成员函数。其功能与构造函数的功能正好相反,是用来释放一个对象,在对象删除前,用它来做一些清理工作

15、。析构函数具有以下一些特点:(1)析构函数名与构造函数名相同,但它前面必须加一个波浪号(),用以区别于构造函数。(2)在定义析构函数时,不能指定任何返回类型,也没有参数,而且不能重载。因此在一个类中只能有一个析构函数。(3)析构函数可以被显示调用,也可以被系统自动调用。,26,析构函数,在下面两种情况下,析构函数会被系统自动调用:如果一个对象被定义在一个函数体内,则当这个函数结束时,该对象的析构函数被自动调用。当一个对象是使用new运算符动态创建的,在使用delete运算符释放它时,delete将会自动调用析构函数。每个类必须有一个析构函数。若没有显式地为一个类定义析构函数,编译系统会自动地生

16、成一个缺省的析构函数,其格式如下::缺省析构函数是一个空函数。实际上什么操作都不进行。,27,析构函数实例,【实例11-1-5】在学生类(包括:学号、姓名、年龄和班级号)中使用构造函数和析构函数。,#include#include#include class TStudent public:TStudent(char*sn,char*name,int age,int cn);TStudent();/说明析构函数 void ShowStudent();private:char sno5;char sname10;int sage;int cno;,28,析构函数实例,TStudent:TStud

17、ent(char*sn,char*name,int age,int cn)定义构造函数 cout构造函数被调用!n;strcpy(sno,sn);strcpy(sname,name);sage=age;cno=cn;void TStudent:ShowStudent()coutsetw(6)snosetw(12)snamesetw(6)sagesetw(5)cnoendl;TStudent:TStudent()/定义析构函数 cout析构函数被调用!n;,29,析构函数实例,/eg9_6.cpp文件#include st.h动态创建s2对象void main()TStudent s1(001,

18、张红,18,1),*s2;s2=new TStudent(002,李力,20,2);coutShowStudent();delete s2;,30,调用构造函数和析构函数的顺序,31,11.3 对象数组,数组不仅可以由简单变量组成,也可以由对象组成,即对象数组的每一个元素都是同类的对象。,例如一个班有50个学生,每个学生的属性包括姓名、性别、年龄、成绩等。这时可以定义一个“学生类”对象数组,每一个数组元素是一个“学生类”对象。例如:/假设已声明了Student类,定义stud数组,有50个元素TStudent stud50;,【格式】类名 对象数组名长度,32,在对象数组中使用构造函数,在建立

19、数组时,同样要调用构造函数。如果有50个元素,需要调用50次构造函数。在需要时可以在定义数组时提供实参以实现初始化。1.构造函数只有一个参数如果构造函数只有一个参数,在定义数组时可以直接在等号后面的花括号内提供实参。例如:TStudent stud3=60,70,78;/合法,3个实参分别传递给3个数组元素的构造函数,33,在对象数组中使用构造函数,2.构造函数有多个参数如果构造函数有多个参数,在定义对象数组时在花括号中分别写出构造函数并指定实参。如果构造函数有3个参数,分别代表学号、年龄、成绩。则可以这样定义对象数组:TStudent Stud3=/调用第1个元素的构造函数,为它提供3个实参

20、TStudent(1001,18,87),TStudent(1002,19,76),TStudent(1003,18,72);,34,对象数组应用实例,【实例11-3-1】定义一个描述学生的类(包括:学号、姓名、年龄和班级号)及该类的对象数组,使用构造函数初始化数据成员。,35,对象数组应用实例,#include#include#include class TStudent public:TStudent(char*sn,char*name,int age,int cn);/说明构造函数 void ShowStudent();private:char sno5;char sname10;int

21、 sage;int cno;,36,对象数组应用实例,TStudent:TStudent(char*sn,char*name,int age,int cn)strcpy(sno,sn);strcpy(sname,name);sage=age;cno=cn;void TStudent:ShowStudent()coutsetw(6)snosetw(12)snamesetw(6)sagesetw(5)cnoendl;,37,对象数组应用实例,/#include st.hvoid main()TStudent s13=TStudent(“001”,“张红”,18,2),TStudent(“002”,

22、“李江”,19,3),TStudent(“003”,“王琴,18,1);cout访问类成员n;coutsetw(6)snosetw(12)snamesetw(6)sagesetw(6)cnon;for(int i=0;i3;i+)s1i.ShowStudent();,38,11.5 静态成员,由于系统只为变量分配存储空间,不为类型分配存储空间,因此,不能用关键词register、auto、extern来修饰类中的成员。但可以用static来修饰成员,被修饰的成员称为静态成员。静态成员有别于其他存储类型的成员,它不是某个对象的成员,而是所有该类对象都共享的成员。可以利用静态成员的这一特性,存储共

23、享信息或进行数据传递。静态成员包括静态数据成员和静态成员函数。,39,11.5.1 静态数据成员,静态数据成员在生成每一个类的对象时并不分配存储空间,而是该类的每个对象共享一个公共的存储空间,并且该类的所有对象都可以直接访问该存储空间。该类的所有对象维护该成员的同一个拷贝,从而实现了同一个类的不同对象之间的数据共享。必须在创建该类的对象之前为静态成员分配存储空间并设置初值。,分配存储空间并设置初值的格式为:静态成员数据类型 类名:静态数据成员=初值;若静态数据成员没有进行初始化,则自动被初始化为0。,40,静态数据成员应用实例,【实例11-5-1】在学生类(包括:学号、姓名、成绩)中,计算学生

24、的总成绩、平均成绩和学生人数。,【编程思路】学生的总成绩、平均成绩和学生人数应该是每个学生共享的数据,因此,将其说明为静态数据成员。,41,静态数据成员应用实例,#include#include#include class TStudent public:TStudent(char*name,char*st_no,float score1);TStudent();void show_st();/输出姓名、学号和成绩 void show_count_sum_avg();/输出学生人数、总成绩和平均成绩private:char*sno;char*sname;float score;static i

25、nt count;/静态数据成员 static float sum;static float avg;,42,静态数据成员应用实例,TStudent:TStudent(char*name,char*st_no,float score1)sname=new charstrlen(name)+1;strcpy(sname,name);sno=new charstrlen(st_no)+1;strcpy(sno,st_no);score=score1;+count;/累加学生人数sum=sum+score;/累加总成绩 avg=sum/count;/计算平均成绩 TStudent:TStudent(

26、)delete sname;delete sno;,43,静态数据成员应用实例,void TStudent:show_st()/输出学生信息 coutsetw(7)sno;coutsetw(8)sname;coutsetw(8)score;void TStudent:show_count_sum_avg()/输出静态数据成员 coutsetw(8)sum;coutsetw(10)avg;coutsetw(8)countendl;int TStudent:count=0;/初始化静态数据成员float TStudent:sum=0.0;float TStudent:avg=0.0;,44,静态数

27、据成员应用实例,#include st.hvoid main()cout sno sname score sum avg countn;TStudent st1(李力,001,92);st1.show_st();st1.show_count_sum_avg();TStudent st2(张红,002,86);st2.show_st();st2.show_count_sum_avg();TStudent st3(杨阳,003,73);st3.show_st();st3.show_count_sum_avg();,45,静态数据成员应用实例,【说明】(1)静态数据成员能在类说明符中声明,但不能在其

28、中定义。(2)对于静态数据成员的初始化不能在构造函数中进行。(3)所有的TStudent对象st1、st2和st3共享静态数据成员count、sum和avg。,46,11.5.2 静态成员函数,静态成员函数和静态数据成员一样,他们都属于类的静态成员,他们都不是对象成员。因此,引用静态成员不需要对象名。静态成员函数只能直接访问类中的静态数据成员,而不能直接访问类中的非静态数据成员,若要访问类中的非静态数据成员,可通过对象来引用。,47,静态成员函数应用实例,【实例11-5-2】在学生类(包括:学号、姓名、成绩)中,计算学生的总成绩、平均成绩和学生人数。利用静态成员函数输出学生的信息。,48,静态

29、成员函数应用实例,#include#include#include class TStudent public:TStudent(char*name,char*st_no,float score1);static void show_st(TStudent x);/静态成员函数 private:char*sno;char*sname;float score;static int count;static float sum;static float avg;,49,静态成员函数应用实例,TStudent:TStudent(char*name,char*st_no,float score1)sn

30、ame=new charstrlen(name)+1;strcpy(sname,name);sno=new charstrlen(st_no)+1;strcpy(sno,st_no);score=score1;+count;/累加学生人数sum=sum+score;/累加总成绩 avg=sum/count;/计算平均成绩,50,静态成员函数应用实例,/在静态成员函数中访问静态数据成员和非静态数据成员void TStudent:show_st(TStudent x)coutsetw(7)x.sno;coutsetw(8)x.sname;coutsetw(8)x.score;coutsetw(8)

31、sum;coutsetw(10)avg;coutsetw(8)countendl;int TStudent:count=0;float TStudent:sum=0.0;float TStudent:avg=0.0;,51,静态成员函数应用实例,#include st.hvoid main()cout sno sname score sum avg countn;TStudent st1(李力,001,92);TStudent:show_st(st1);/访问静态成员函数 TStudent st2(张红,002,86);TStudent:show_st(st2);TStudent st3(杨阳

32、,003,73);TStudent:show_st(st3);,【说明】在静态成员函数中可以直接访问静态数据成员,访问非静态数据成员要指明其对象,如x.sno。,52,11.6 友元,友元提供了不同类或对象的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。对于一个类,可以利用关键字friend将一般函数、其他类的成员函数或者其他类声明为该类的友元,使得这个类中本来隐藏的信息(包括私有成员和保护成员)可以被友元所访问。,53,11.6.1 友元函数,友元函数是一种定义在类外面的普通函数,而不是类的成员函数。为区别友元函数与类的成员函数,在说明友元函数时前面加关键字friend。尽管友

33、元函数不是类的成员函数,但它可以访问类的所有成员,包括私有成员、保护成员和公有成员。友元函数要在类定义时说明,说明时要在其函数名前加上关键字friend。该说明可以放在公有部分,也可以放在私有部分。友元函数的定义既可以在类内部进行,也可以在类外进行。,54,友元函数应用实例,【实例11-6-1】定义一个点(Tpoint)类,计算两点之间的距离。,【编程思路】本实例利用友元函数访问Tpoint类中的数据成员,从而计算两点之间的距离。,55,友元函数应用实例,#include class TPoint public:TPoint(int x,int y);int getX()return xVal

34、;int getY()return yVal;private:int xVal;int yVal;friend void Distance(TPoint a,TPoint b);/说明友元函数;TPoint:TPoint(int x,int y)if(x=0,56,友元函数应用实例,/利用友元函数访问对象的成员void Distance(TPoint a,TPoint b)double d;int dx=;int dy=;d=sqrt(dx*dx+dy*dy);coutThe distance between;coutp1(a.getX(),a.getY()and;coutp2(b.getX(

35、),b.getY();cout is dendl;,57,友元函数应用实例,#include#include pt.hvoid main()TPoint p1(10,20),p2(12,6);double d;Distance(p1,p2);,【说明】(1)友员的声明可以放置在类中的任意位置。(2)为了确保数据的完整性,及数据封装与隐藏的原则,建议尽量不使用或少使用友元。,58,11.6.2 友元类,一个类作为另一个类的友元时,该类称为友元类。友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。,友员的说明可以放置在类中的任意位置。说明方法如下

36、:friend 类名;/友元类类名,【说明】(1)友元关系不能被继承。(2)友元关系是单向的,不具有交换性。若类X是类Y的友元,类Y不一定是类X的友元,要看在类中是否有相应的声明。(3)友元关系不具有传递性。若类X是类Y的友元,类Y是Z的友元,类X不一定是类Z的友元。,59,友元类应用实例,【实例11-6-2】给定两个点,计算这两点之间的距离,及由这两个点构成的矩形面积。,【编程思路】本实例可以定义两个类,点TPoint类和矩形TBox类,将TBox类说明为TPoint类的友元类,这样就可以访问TPoint类中的成员。,60,友元类应用实例,#include class TBox;class

37、TPoint public:TPoint();TPoint(int x,int y);int getX()return xVal;int getY()return yVal;/说明TBox为TPoint的友元类 friend void Distance(TPoint a,TPoint b);private:int xVal;int yVal;friend class TBox;,61,友元类应用实例,TPoint:TPoint(int x,int y)xVal=x;yVal=y;void Distance(TPoint a,TPoint b)double d;int dx=;int dy=;d

38、=sqrt(dx*dx+dy*dy);coutThe distance between;coutp1(a.getX(),a.getY()and;coutp2(b.getX(),b.getY();cout is dendl;,62,友元类应用实例,class TBox public:void area(TPoint a,TPoint b);void ShowPoint(TPoint x);void TBox:area(TPoint a,TPoint b)int s;int dx=);int dy=);s=dx*dy;coutThe area of box is sendl;/在TBox类中访问T

39、Point类中的成员void TBox:ShowPoint(TPoint x)coutp(x.xVal,x.yVal);,63,友元类应用实例,#include#include pt.hvoid main()TPoint p1(10,20),p2(15,6);TBox pxy;double d,s=0;Distance(p1,p2);pxy.area(p1,p2);,【说明】(1)TBox说明为TPoint的友员类,因此,TBox类中的所有成员函数可以访问TPoint类中的成员。(2)友元类不同于友元函数,友元类中的所有成员函数都是另一个类的友元函数。,64,1.掌握构造函数和析构函数的使用2.掌握静态成员的使用3.掌握友元的使用,小结,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号