第十章构造函数和析构函数.ppt

上传人:本田雅阁 文档编号:3131305 上传时间:2019-07-14 格式:PPT 页数:32 大小:545.02KB
返回 下载 相关 举报
第十章构造函数和析构函数.ppt_第1页
第1页 / 共32页
第十章构造函数和析构函数.ppt_第2页
第2页 / 共32页
第十章构造函数和析构函数.ppt_第3页
第3页 / 共32页
第十章构造函数和析构函数.ppt_第4页
第4页 / 共32页
第十章构造函数和析构函数.ppt_第5页
第5页 / 共32页
点击查看更多>>
资源描述

《第十章构造函数和析构函数.ppt》由会员分享,可在线阅读,更多相关《第十章构造函数和析构函数.ppt(32页珍藏版)》请在三一文库上搜索。

1、Visual C+程序设计,徐 建 南京理工大学计算机系,【学习目标】 理解类的构造函数和析构函数。 【重点与难点】 构造函数(包括拷贝构造函数)和析构函数的概念和用法;,第十章 构造函数和析构函数,10.1 构造函数 10.1.1 构造函数的定义 10.1.2 缺省构造函数 10.1.3 拷贝构造函数 10.1.4 单个参数的构造函数 10.2 析构函数 10.3 对象的生存期 10.3.1 全局对象、静态对象与局部对象 10.3.2 自由存储对象 10.4 成员对象 10.5 对象数组,10.1 构造函数,构造函数(功能:创建对象时,使用给定值将对象初始化) 建立一个对象时,常常需要作某些

2、初始化的工作(例如对数据赋予初值),C+提供了一种特殊的成员函数构造函数 (constructor),这种函数与其它成员不同,不需要用户发“消息”来激活它,而是在建立对象时由系统自动执行。构造函数是由用户定义的,它必须与类名同名,以便系统能识别它并把它作为构造函数。,10.1.1 构造函数的定义,构造函数的特点:,构造函数名字必须与类名相同。 构造函数是成员函数,函数体可写在类体内,也可写在类体外。 构造函数是一个特殊的函数,无返回值,不指定类型,也不需要加void类型声明。 构造函数可带参数,可不带参数,也可指定参数的缺省值。因此构造函数可重载。 程序中不能直接调用构造函数,在创建对象时系统

3、自动调用构造函数。 静态对象首次创建后不再重新产生。,class Date public: Date(int y, int m, int d); /说明构造函数 Date(int y=2000) /重载构造函数 year=y; month=10;day=1; cout“Constructor of Date with 1 parameter.“endl; int IsLeapYear(); void Print(); private: int year,month,day; ; Date: Date(int y,int m,int d) /类外定义构造函数 year=y; month=m; d

4、ay=d; cout“Constructor of Date with 3 parameter.“endl; int Date:IsLeapYear() return (year%4=0 ,/Example 10_1 #include void main(void) Date date1(2002,10,1),date2; /A cout“date1: “; date1.Print(); cout“date2: “; date2.Print(); if (date2.IsLeapYear() cout“date2 is a leapyear.“endl; else cout“date2 is

5、not a leapyear.“endl; ,10.1.2 缺省构造函数,在定义类时,若没有定义类的构造函数,则编译器自动产生一个缺省的构造函数,该函数什么事也不做; 其形式为: :() 在定义类时,若定义了类的构造函数,则编译器就不产生缺省的构造函数; 在类中,若定义了没有参数的构造函数,或各参数均有缺省值的构造函数也称为缺省的构造函数,缺省的构造函数只能有一个; 产生对象时,系统必定要调用构造函数,所以任一对象的构造函数必须唯一。,10.1.3 拷贝构造函数,拷贝构造函数是一种特殊的构造函数。它的功能是用一个已知的对象来初始化一个正在创建的同类对象。 作用:完成对象间的数据成员值的拷贝。,

6、其特点如下:,1. 该函数名同类名,并且该函数也不被指定返回类型。,2. 该函数只有一个参数,对同类对象的引用。,3. 每个类都有各自的拷贝构造函数,其格式如下所示:,:( &),4. 如果类中没有说明拷贝构造函数,则编译系统自动生成一个具有上述形式的缺省拷贝构造函数,作为该类的公有成员。,class Date public: Date(int y, int m, int d); Date(int y=2000) year=y; month=10; day=1; cout“Constructor of Date with 1 parameter.“endl; Date(Date ,#inclu

7、de /Example 10_2 void main(void) Date date1(2002,10,1); Date date2(date1); /A cout“date1: “; date1.Print(); date2 = fun(date1); cout“date2: “; date2.Print(); ,Date fun(Date d) /B return d; /C,Date date2;,程序输出结果如下: Constructor of Date with 3 parameter. Copy constructor of Date. date1: 2002.10.1 date2

8、: 2002.10.1,程序输出结果如下:Constructor of Date with 3 parameter. Constructor of Date with 1 parameter. date1: 2000.1.1 Copy constructor of Date. Copy constructor of Date. date2: 2000.1.1,调用拷贝构造函数的三种情况:,(1)用类的一个已知的对象去初始化该类的另一个正在创建的对象。 (2)采用传值调用方式时,把对象作为函数实参传递给函数形参。 (3)对象作为函数返回值。,#include /Example 10_3 #inc

9、lude class S char *ptr; public: S(char *p) if(!p) ptr=NULL; else ptr=new charstrlen(p)+1; strcpy(ptr,p); void Del() delete ptr; ; void main() S s1(“abcdef“); s1.Del(); s2.Del();,S s2(s1);,如果一个类中有指针成员,使用缺省的复制构造函数初始化对象就会出现问题。,10.2 析构函数,在一个对象消亡时被调用,因此常用来做善后工作,比如对象保持的动态空间的释放或对象所在的函数已调用完毕等。,析构函数的特点:,1. 析

10、构函数的名字同类名,并在前面加“”字符,用来与构造函数加以区别。析构函数不指定数据类型,并且也没有参数。,4. 一个类中只可能定义一个析构函数,不能重载。,2. 不能指定析构函数返回值,也不能指定为void类型。,3. 析构函数,不可带参数。,5. 如果用户没有编写析构函数,系统会自动生成一个公有的缺省的析构函数。形式为: :( ) ,全局对象:如果一个对象的作用域是整个程序,则当这个程序结束时,该对象的析构函数被自动调用。 局部对象:如果一个对象被定义在一个函数体内,则当这个函数结束时,该对象的析构函数被自动调用。 动态创建的对象:当一个对象是用new运算符被动态创建的,在使用delete运

11、算符释放它时,delete会自动调用析构函数。,6. 析构函数可以被用户调用,也可以被系统自动调用,在下面三种情况,析构函数会被自动调用:,10.1.4 单个参数的构造函数用于类型转换,/Example 10_4 #include class Ex1 int x; public: Ex1( int a) x=a; cout“x=”x” 调用了构造函数!“endl; Ex1() cout“调用了析构函数!“endl; ; void main() Ex1 x1(50); Ex1 x2=100; x2=200; ,结果输出: X=50 调用了构造函数! X=100 调用了构造函数! X=200 调用

12、了构造函数! 调用了析构函数! 调用了析构函数! 调用了析构函数!,等同于x2(100) 的写法,条件是构造函数 的形参只有一个的情况下,x=200;的实际效果: (内部转换成如下的操作) Ex1 tmp(200); x2=tmp; ,当构造函数只有一个参数时,才能象以上这样使用。,#include /Example 10_5 class Ex2 int x,y; public: Ex2( int a,int b) x=a;y=b; cout“x=”x“ y=”y“ 调用了构造函数!“endl; Ex2() cout“调用了析构函数!“endl; ; void main() Ex2 x1(50

13、,100); x1= Ex2(300,600); ,输出结果: x=50 y=100 调用了构造函数! x=300 y=600 调用了构造函数! 调用了析构函数! 调用了析构函数!,内部处理为: Ex2 tmp(300,600); x1=tmp; ,构造函数有多个参数的情况:,#include /Example 10_6 #include class Person char *name; public: Person(char *s) name=new char strlen(s)+1; strcpy(name,s); void GetName(char *s) strcpy(s,name);

14、 Person()delete name; void Copy(Person s) if(name!=NULL) delete name; name= new charstrlen(s.name)+1; strcpy(name,s.name); ; void main() Person x (“张三“),y (“李四“); y.Copy(x); ,s前的&不能省, 当采用类对象值传 递时,会自动调用 拷贝构造函数, 函数结束前,自 动调用析构函数,程序执行出错!,s,#include /Example 10_7 class Test public: Test() /缺省构造函数 val=0;

15、cout“Default constructor.“endl; Test(int n) /重载构造函数 val=n; cout“Constructor of “valendl; Test(const Test /D ,void main(void) Test t1(1); /E Test t2=t1; /F Test t3; /G t3=t1; fun1(t2); /H t3=fun2(); /I /J,Constructor of 1 Copy constructor. Default constructor. Copy constructor. Destructor of 1 Defaul

16、t constructor. Copy constructor. Destructor of 0 Destructor of 0 Destructor of 0 Destructor of 1 Destructor of 1,10.3 对象的生存期 10.3.1 全局对象、静态对象与局部对象,对象的生存期是指对象从被创建开始到被撤消范围的时间。对象按生存期可分为3类:局部对象、静态对象和全局对象。 局部对象:当执行到定义对象的语句时,产生对象并调用构造函数;当执行到结束局部对象的作用域时,调用析构函数后撤消该对象。 静态对象:当程序第一次执行所定义的静态对象时,产生该对象;直到程序结束时撤消该

17、对象。 全局对象:在程序开始执行时,调用构造函数创建该对象,程序结束时调用析构函数撤消该对象。,#include /Example 10_8 #include class Test char str50; public: Test(char *s); Test(); ; Test:Test(char *s) strcpy(str,s); cout“Constructor of “strendl; Test:Test() cout“Destructor of “strendl; void fun(void) Test FunObject(“FunObject“); /局部对象 static Te

18、st StaticObject(“StaticObject“); /静态对象 cout“In fun() “endl; Test GlobalObject(“GlobalObject”); /全局对象 void main(void) Test MainObject(“MainObject“); /局部对象 cout“In main(), before called fun() “endl; fun(); cout“In main(), after called fun() “endl; ,Constructor of GlobalObject Constructor of MainObject

19、 In main(), before called fun() Constructor of FunObject Constructor of StaticObject In fun() Destructor of FunObject In main(), after called fun() Destructor of MainObject Destructor of StaticObject Destructor of GlobalObject,全局对象的作用域最大,生存期最长;静态对象次之;局部对象的作用域最小,生存期也最短。,10.3.2 自由存储对象(动态对象),用运算符new产生的

20、对象称其为自由存储对象或动态对象。这种对象必须使用运算符delete来撤消。 首先为类的对象分配一个内存空间,然后自动调用构造函数来初始化对象的成员数据,最后返回该动态对象的起始地址。 用new运算符创建动态对象时,要调用构造函数;用delete删除动态对象时,要调用析构函数。,#include /Example 10_9 class Test int X,Y; public: Test(); /缺省构造函数 Test(int i,int j); /重载构造函数 Test() /析构函数 cout“Destructor called: ” coutX,Yendl; void Set(int i

21、,int j); void Print() coutX“, “Yendl; ; Test:Test() X=Y=0; cout“Default constructor called. ”endl; Test:Test(int i,int j) X=i; Y=j; cout“Constructor called: ”X,Yendl; void Test:Set(int i,int j) X=i; Y=j; ,Constructor called: 1,2 Constructor called: 5,6 1, 2 5, 6 Destructor called: 1,2 Destructor cal

22、led: 5,6,void main(void) Test *ptr1,*ptr2; ptr1=new Test(1,2); /A ptr2=new Test(5,6); /B ptr1-Print(); ptr2-Print(); delete ptr1; /C delete ptr2; ,10.4 成员对象,在定义一个新类时,可把一个已定义类的对象作为该类的成员。产生这新定义类的对象时,也要对它的成员对象进行初始化,且只能通过这新类的构造函数来对它的所有数据成员初始化。要对成员对象进行初始化,必须通过调用其成员对象的构造函数来实现。 新类构造函数形式为: 类名:类名(参数表):c1(参数表

23、),cn(参数表) 函数体; ,注意: 当建立类C的对象时,先调用各个对象成员的构造函数(对对象成员的构造函数的调用顺序取决于这些对象成员在类中说明的顺序 ),初始化相应的对象成员,然后才执行类C的构造函数,初始化类C中的其它成员。 c1 cn的次序可任意,但习惯上按说明次序定义。 析构函数的执行顺序与构造函数的执行顺序相反。 当类自己不需要构造函数而其对象成员需构造初始化,则自己必须有一个构造函数,不能依赖于缺省的构造函数。,#include /Example 10_10 class Counter int val; public: Counter() /缺省构造函数 val=0; cout

24、“Default Constructor of Counter“endl; Counter(int x) /重载构造函数 val=x; cout“Constructor of Counter:“valendl; Counter() /析构函数 cout“Destructor of Counter:“valendl; ;,class Example Counter c1,c2; /A int val; public: Example() /缺省构造函数 val=0; cout“Default Constructor of Example“endl; Example(int x):c2(x) /重

25、载构造函数 val=x; cout“Constructor of Example:“valendl; Example() cout“Destructor of Example:“valendl; void Print() cout“value=“valendl; ;,Default Constructor of Counter Default Constructor of Counter Default Constructor of Example Default Constructor of Counter Constructor of Counter:4 Constructor of Ex

26、ample:4 value=4 Destructor of Example:4 Destructor of Counter:4 Destructor of Counter:0 Destructor of Example:0 Destructor of Counter:0 Destructor of Counter:0,void main(void) Example e1,e2(4); /B e2.Print(); /C ,#include /Example 10_11 #include class Point double x,y,z; public: Point(double a=0,dou

27、ble b=0,double c=0) x=a; y=b; z=c; void Set(double a,double b,double c) Point(a,b,c); void Print() cout“x=“x“y=“y“z=“zendl; double Distance(Point ,class Line Point x1,x2; public: Line(double a1,double b1,double c1,double a2, double b2,double c2):x1(a1,b1,c1),x2(a2,b2,c2) double Lenth() return x1.Dis

28、tance(x2); void PrintLine() cout“Line:“endl; x1.Print(); x2.Print(); ;,void main() Line l1(1,2,3,4,5,6); Line l2(2,3,4,8,9,10); l1.PrintLine(); l2.PrintLine(); cout“Lenth1=“l1.Lenth()endl; cout“Lenth2=“l2.Lenth()endl; ,Line: x=1 y=2 z=3 x=4 y=5 z=6 Line: x=2 y=3 z=4 x=8 y=9 z=10 Lenth1=5.19615 Lenth

29、2=10.3923,#include /Example 10_12 class A public: int x,y; A(int a,int b) x=a;y=b; ; class B public: int Length,Width; B(int a,int b) Length=a;Width=b; ; class C public: int r,High; A a1; B b1; C(int a,int b, int c, int d,int e,int f):a1(e,f),b1(c,d) r=a;High=b; ;,void main(void) C c1(25,35,45,55,65

30、,100); coutc1.rn; coutc1.Highn; coutc1.a1.xn; coutc1.a1.yn; coutc1.b1.Lengthn; coutc1.b1.Widthn; ,作业:,10.5 对象数组,对象数组是指数组元素为对象的数组,该数组中所有元素必须是同一个类的对象。对象数组的定义、赋值和使用与普通数组一样,只是数组的元素与普通数组不同,它是类的对象。 对象数组的定义格式为: ; 例如:DATE dates5; 使用对象数组成员的一般格式是: . 例如:dates0.year;,#include /Example 10_13 class DATE int month

31、,day,year; public: DATE() month=day=year=0; cout“Default constructor called.“endl; DATE(int m,int d,int y) month=m; day=d; year=y; cout“Constructor called.“dayendl; DATE() cout“Destructor called.“dayendl; void Print() cout“Month=“month“,Day=“day“,Year=“yearendl; ; void main(void) DATE dates3=DATE(7,

32、22,1998),DATE(7,23,1998); /A dates2=DATE(7,25,1998); /B for(int i=0;i3;i+) datesi.Print(); /C ,Constructor called.22 Constructor called.23 Default constructor called. Constructor called.25 Destructor called.25 Month=7,Day=22,Year=1998 Month=7,Day=23,Year=1998 Month=7,Day=25,Year=1998 Destructor called.25 Destructor called.23 Destructor called.22,DATE temp(7,25,1998); date2 = temp;,(参数表),

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

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1