c构造函数与析构函数学习教案

上传人:可**** 文档编号:94401218 上传时间:2022-05-22 格式:PPTX 页数:53 大小:249.60KB
收藏 版权申诉 举报 下载
c构造函数与析构函数学习教案_第1页
第1页 / 共53页
c构造函数与析构函数学习教案_第2页
第2页 / 共53页
c构造函数与析构函数学习教案_第3页
第3页 / 共53页
资源描述:

《c构造函数与析构函数学习教案》由会员分享,可在线阅读,更多相关《c构造函数与析构函数学习教案(53页珍藏版)》请在装配图网上搜索。

1、会计学1c构造函数与析构函数构造函数与析构函数第一页,编辑于星期六:三点 五十五分。构造函数和析构函数是在类体中说明的两种构造函数和析构函数是在类体中说明的两种特殊特殊的成员函数的成员函数。构造函数是在创建对象时,使用给定的值来将对象构造函数是在创建对象时,使用给定的值来将对象初始化。初始化。析构函数的功能正好相反,是在系统释放对象析构函数的功能正好相反,是在系统释放对象前,对对象做一些善后工作前,对对象做一些善后工作。第1页/共53页第二页,编辑于星期六:三点 五十五分。构造函数是类的成员函数,系统约定构造函数构造函数是类的成员函数,系统约定构造函数名必须与类名相同。名必须与类名相同。构造函

2、数提供了初始化对构造函数提供了初始化对象的一种简单的方法象的一种简单的方法。构造函数构造函数可以带参数、可以重载可以带参数、可以重载,同时没有返回,同时没有返回值。值。第2页/共53页第三页,编辑于星期六:三点 五十五分。class Afloat x,y;public:A(float a,float b) x=a; y=b;/构造函数,初始化对象构造函数,初始化对象float Sum(void) return x+y; void Set(float a,float b) x=a;y=b;Print(void) coutx=xty=yendl;void main(void)A a1(2.0, 3

3、.0);/定义时调用构造函数初始化定义时调用构造函数初始化A a2(1.0,2.0);a2.Set(10.0, 20.0); /利用成员函数重新为对象赋值利用成员函数重新为对象赋值 a1.Print();a2.Print();第3页/共53页第四页,编辑于星期六:三点 五十五分。对构造函数,说明以下几点:对构造函数,说明以下几点:1.构造函数的函数名必须与类名相同构造函数的函数名必须与类名相同。构造函构造函数的主要作用是完成初始化对象的数据成员数的主要作用是完成初始化对象的数据成员以及其它的初始化工作以及其它的初始化工作。2. 在定义构造函数时,在定义构造函数时,不能指定函数返回值的不能指定函

4、数返回值的类型,也不能指定为类型,也不能指定为void类型类型。3. 一个类可以定义若干个构造函数。当定义多一个类可以定义若干个构造函数。当定义多个构造函数时,个构造函数时,必须满足函数重载的原则。必须满足函数重载的原则。第4页/共53页第五页,编辑于星期六:三点 五十五分。4.构造函数可以指定参数的缺省值。构造函数可以指定参数的缺省值。5.若定义的类要说明该类的对象时,构造函数若定义的类要说明该类的对象时,构造函数必须是必须是公有的成员函数公有的成员函数。如果定义的类仅用于。如果定义的类仅用于派生其它类时,则可将构造函数定义为派生其它类时,则可将构造函数定义为保护的保护的成员函数成员函数。由

5、于构造函数属于类的成员函数,它对私有由于构造函数属于类的成员函数,它对私有数据成员、保护的数据成员和公有的数据成数据成员、保护的数据成员和公有的数据成员员均能进行初始化均能进行初始化。第5页/共53页第六页,编辑于星期六:三点 五十五分。class Afloat x,y;public:A(float a, float b=10) x=a; y=b; A() x=0; y=0; void Print(void) coutxtyendl; ;void main(void) A a1, a2(20.0), a3(3.0, 7.0); a1.Print(); a2.Print(); a3.Print(

6、); 00201037带缺省参数的构造函数带缺省参数的构造函数不带参数的构造函数不带参数的构造函数每一个对象必每一个对象必须要有相应的须要有相应的构造函数构造函数第6页/共53页第七页,编辑于星期六:三点 五十五分。每一个对象必须要有相应的构造函数每一个对象必须要有相应的构造函数若没有显式定义构造函数,系若没有显式定义构造函数,系统默认缺省的构造函数。统默认缺省的构造函数。class Afloat x,y;public:A() void Print(void) coutxtyendl; ;隐含的缺省的构造函数隐含的缺省的构造函数A a1, a2;只允许这样定义对象只允许这样定义对象对象开辟了空

7、间,但没有初始化对象开辟了空间,但没有初始化第7页/共53页第八页,编辑于星期六:三点 五十五分。对局部对象,静态对象,全局对象的初始化对局部对象,静态对象,全局对象的初始化对对于局部对象,每次定义对象时,都要调用构造于局部对象,每次定义对象时,都要调用构造函数。函数。对于静态对象,是在首次定义对象时,调用构造对于静态对象,是在首次定义对象时,调用构造函数的,且由于对象一直存在,函数的,且由于对象一直存在,只调用一次构造只调用一次构造函数函数。对于全局对象,是对于全局对象,是在在main函数执行之前调用函数执行之前调用构造函数的构造函数的。第8页/共53页第九页,编辑于星期六:三点 五十五分。

8、class A int x,y; public: A(int a) x=a; cout“1n”; A(int a, int b) x=a,y=b;cout“2n”;A a1(3);void f(void) A b(2,3);void main(void) A a2(4,5); f(); f();1222第9页/共53页第十页,编辑于星期六:三点 五十五分。class Afloat x,y;public: A(float a, float b)x=a;y=b;cout初始化自动局部对象初始化自动局部对象n; A()x=0; y=0; cout初始化静态局部对象初始化静态局部对象n; A(floa

9、t a)x=a; y=0; cout初始化全局对象初始化全局对象n; void Print(void) coutxtyendl; ;A a0(100.0);/定义全局对象定义全局对象void f(void) cout 进入进入f()函数函数n;A a2(1,2); static A a3; /初始化局部静态对象初始化局部静态对象 void main(void) cout进入进入main函数函数n; A a1(3.0, 7.0);/定义局部自动对象定义局部自动对象 f(); f(); 初始化全局对象初始化全局对象进入进入main函数函数初始化自动局部对象初始化自动局部对象进入进入f()函数函数初

10、始化局部静态变量初始化局部静态变量进入进入f()函数函数初始化自动局部对象初始化自动局部对象初始化自动局部对象初始化自动局部对象第10页/共53页第十一页,编辑于星期六:三点 五十五分。缺省的构造函数缺省的构造函数 在定义类时,若没有定义类的构造函数,则编在定义类时,若没有定义类的构造函数,则编译器译器自动自动产生一个缺省的构造函数,其格式为:产生一个缺省的构造函数,其格式为:className:className() 缺省的构造函数并不对所产生对象的数据成员赋缺省的构造函数并不对所产生对象的数据成员赋初值初值;即;即新产生对象的数据成员的值是不确定的。新产生对象的数据成员的值是不确定的。 第

11、11页/共53页第十二页,编辑于星期六:三点 五十五分。class Afloat x,y;public:A()/缺省的构造函数,编译器自动产生缺省的构造函数,编译器自动产生,可以不写可以不写float Sum(void) return x+y; void Set(float a,float b) x=a;y=b; void Print(void) coutx=xty=yendl; ;void main(void)A a1,a2;/产生对象时,自动调用缺省的构造函数,不赋值产生对象时,自动调用缺省的构造函数,不赋值a1.Set (2.0,4.0);couta1: ; a1.Print ();co

12、uta1.sum=a1.Sum ()endl;a2.Print();/打印随机值打印随机值第12页/共53页第十三页,编辑于星期六:三点 五十五分。关于缺省的构造函数,说明以下几点:关于缺省的构造函数,说明以下几点:1、在定义类时,、在定义类时,只要只要显式显式定义了一个类的构定义了一个类的构造函数,则编译器就不产生缺省的构造函数造函数,则编译器就不产生缺省的构造函数2、所有的对象在定义时,必须调用构造函数所有的对象在定义时,必须调用构造函数不存在没有构造函数的对象!不存在没有构造函数的对象!第13页/共53页第十四页,编辑于星期六:三点 五十五分。class Afloat x,y;publi

13、c: A(float a,float b)x=a;y=b; void Print(void)coutxtyendl;void main(void)A a1;A a2(3.0,30.0);显式定义了构造函数,不产显式定义了构造函数,不产生缺省的构造函数生缺省的构造函数error,定义时,没有构造定义时,没有构造函数可供调用函数可供调用第14页/共53页第十五页,编辑于星期六:三点 五十五分。3、在类中,若定义了没有参数的构造函数,或、在类中,若定义了没有参数的构造函数,或各参数均有缺省值的构造函数也称为缺省的构造各参数均有缺省值的构造函数也称为缺省的构造函数,函数,缺省的构造函数只能有一个。缺省

14、的构造函数只能有一个。4、产生对象时,系统必定要调用构造函数。、产生对象时,系统必定要调用构造函数。所以任所以任一对象的构造函数必须唯一一对象的构造函数必须唯一。第15页/共53页第十六页,编辑于星期六:三点 五十五分。class Afloat x,y;public: A(float a=10,float b=20)x=a;y=b; A() void Print(void)coutxtyendl;void main(void)A a1;A a2(3.0,30.0);两个函数均为缺省两个函数均为缺省的构造函数的构造函数两个构造函数均可供调用,构造函数不唯一两个构造函数均可供调用,构造函数不唯一第

15、16页/共53页第十七页,编辑于星期六:三点 五十五分。构造函数与构造函数与new运算符运算符 可以使用可以使用new运算符来运算符来动态地动态地建立对象。建立建立对象。建立时时要自动调用构造函数要自动调用构造函数,以便完成初始化对象的数,以便完成初始化对象的数据成员。最后返回这个动态对象的起始地址。据成员。最后返回这个动态对象的起始地址。用用new运算符产生的动态对象,在不再使用这种运算符产生的动态对象,在不再使用这种对象时,必须用对象时,必须用delete运算符来释放对象所占用的存运算符来释放对象所占用的存储空间。储空间。 用用new建立类的对象时,可以使用参数初始化动态建立类的对象时,可

16、以使用参数初始化动态空间。空间。 第17页/共53页第十八页,编辑于星期六:三点 五十五分。class Afloat x,y;public:A(float a, float b)x=a;y=b; A()x=0; y=0;void Print(void) coutxtyPrint(); pa2-Print(); delete pa1; /用用delete释放空间释放空间 delete pa2; /用用delete释放空间释放空间3500第18页/共53页第十九页,编辑于星期六:三点 五十五分。析构函数析构函数 析构函数的作用与构造函数正好相反,析构函数的作用与构造函数正好相反,是在对象的生命是在

17、对象的生命期结束时,释放系统为对象所分配的空间,即要撤消一期结束时,释放系统为对象所分配的空间,即要撤消一个对象。个对象。析构函数也是类的成员函数,定义析构函数的格式为:析构函数也是类的成员函数,定义析构函数的格式为:ClassName:ClassName( ) ./ 函数体函数体; 第19页/共53页第二十页,编辑于星期六:三点 五十五分。析构析构 函数的特点如下:函数的特点如下:1、析构函数是、析构函数是成员函数成员函数,函数体可写在类体内,函数体可写在类体内,也可写在类体外。也可写在类体外。2、析构函数是一个特殊的成员函数,函数名必须析构函数是一个特殊的成员函数,函数名必须与类名相同,并

18、在其与类名相同,并在其前面加上字符前面加上字符“”,以便和构造,以便和构造函数名相区别函数名相区别。3、析构函数、析构函数不能带有任何参数,不能有返回值,不指不能带有任何参数,不能有返回值,不指定函数类型。定函数类型。第20页/共53页第二十一页,编辑于星期六:三点 五十五分。在程序的执行过程中,当遇到某一对象的生存期在程序的执行过程中,当遇到某一对象的生存期结束时,系统自动调用析构函数,然后再收回为结束时,系统自动调用析构函数,然后再收回为对象分配的存储空间。对象分配的存储空间。4、一个类中,只能定义一个析构函数,、一个类中,只能定义一个析构函数,析构函数不允析构函数不允许重载。许重载。5、

19、析构函数是在撤消对象时由系统自动调用的。、析构函数是在撤消对象时由系统自动调用的。第21页/共53页第二十二页,编辑于星期六:三点 五十五分。class Afloat x,y;public: A(float a,float b) x=a;y=b;cout调用非缺省的构造函数调用非缺省的构造函数n; A() x=0; y=0; cout调用缺省的构造函数调用缺省的构造函数n ; A() cout调用析构函数调用析构函数n; void Print(void) coutxtyendl;void main(void)A a1; A a2(3.0,30.0);cout退出主函数退出主函数n;调用缺省的构

20、造函数调用缺省的构造函数调用非缺省的构造函数调用非缺省的构造函数退出主函数退出主函数调用析构函数调用析构函数调用析构函数调用析构函数第22页/共53页第二十三页,编辑于星期六:三点 五十五分。 在程序的执行过程中,对象如果用在程序的执行过程中,对象如果用new运运算符开辟了空间,则在类中算符开辟了空间,则在类中应该应该定义一个析构定义一个析构函数,并在析构函数中使用函数,并在析构函数中使用delete删除由删除由new分分配的内存空间。配的内存空间。因为在撤消对象时,系统自动因为在撤消对象时,系统自动收回为对象所分配的存储空间,而不能自动收回收回为对象所分配的存储空间,而不能自动收回由由new

21、分配的动态存储空间。分配的动态存储空间。第23页/共53页第二十四页,编辑于星期六:三点 五十五分。class Strchar *Sp; int Length;public:Str(char *string) if(string)Length=strlen(string); Sp=new charLength+1;strcpy(Sp,string); else Sp=0;void Show(void)coutSpendl;Str() if(Sp) delete Sp;void main(void)Str s1(Study C+);s1.Show();在构造函数中将在构造函数中将成成员数据指针员

22、数据指针指向动态指向动态开辟的内存开辟的内存用初值为开辟用初值为开辟的内存赋值的内存赋值析构函数,当释放对析构函数,当释放对象时收回用象时收回用new开开辟的空间辟的空间第24页/共53页第二十五页,编辑于星期六:三点 五十五分。Study C+ 0stringLength=strlen(string);Sp=new charLength+1;Spnew开辟的空间开辟的空间strcpy(Sp,string);Study C+ 0第25页/共53页第二十六页,编辑于星期六:三点 五十五分。用用new运算符为对象分配动态存储空间时,调用运算符为对象分配动态存储空间时,调用了构造函数,用了构造函数,

23、用delete删除这个空间时,调用了析构删除这个空间时,调用了析构函数。函数。当使用运算符当使用运算符delete删除一个由删除一个由new动态产生动态产生的对象时,它首先调用该对象的析构函数,然后的对象时,它首先调用该对象的析构函数,然后再释放这个对象占用的内存空间再释放这个对象占用的内存空间。可以用可以用new运算符为对象分配存储空间,如:运算符为对象分配存储空间,如:A *p;p=new A;这时必须用这时必须用delete才能释放这一空间。才能释放这一空间。delete p;第26页/共53页第二十七页,编辑于星期六:三点 五十五分。class Afloat x,y;public: A

24、(float a, float b)x=a;y=b;cout调用了构造函数调用了构造函数n; void Print(void) coutxtyendl; A() cout调用了析构函数调用了析构函数n; ;void main(void) coutPrint(); delete pa1; /调用析构函数调用析构函数 cout退出退出main()函数函数n;进入进入main()函数函数调用了构造函数调用了构造函数35调用了析构函数调用了析构函数退出退出main()函数函数第27页/共53页第二十八页,编辑于星期六:三点 五十五分。不同存储类型的对象调用构造函数及析构函数不同存储类型的对象调用构造函

25、数及析构函数 1、对于全局定义的对象对于全局定义的对象(在函数外定义的对象),(在函数外定义的对象),在程序开始执行时,调用构造函数;到程序结束时,在程序开始执行时,调用构造函数;到程序结束时,调用析构函数。调用析构函数。2、对于局部定义的对象对于局部定义的对象(在函数内定义的对象),当(在函数内定义的对象),当程序执行到定义对象的地方时,调用构造函数;在退程序执行到定义对象的地方时,调用构造函数;在退出对象的作用域时,调用析构函数。出对象的作用域时,调用析构函数。3、用用static定义的局部对象定义的局部对象,在首次到达对象的定义,在首次到达对象的定义时调用构造函数;到程序结束时,调用析构

26、函数时调用构造函数;到程序结束时,调用析构函数第28页/共53页第二十九页,编辑于星期六:三点 五十五分。 4、对于用对于用new运算符动态生成的对象运算符动态生成的对象,在产生对象,在产生对象时调用构造函数,只有使用时调用构造函数,只有使用delete运算符来释放对运算符来释放对象时,才调用析构函数。若不使用象时,才调用析构函数。若不使用delete来撤消动态来撤消动态生成的对象,程序结束时,对象仍存在,并占用生成的对象,程序结束时,对象仍存在,并占用相应的存储空间,相应的存储空间,即系统不能自动地调用析构函数即系统不能自动地调用析构函数来撤消动态生成的对象。来撤消动态生成的对象。第29页/

27、共53页第三十页,编辑于星期六:三点 五十五分。class Afloat x,y;public: A(float a, float b)x=a;y=b;cout初始化自动局部对象初始化自动局部对象n; A()x=0; y=0; cout初始化静态局部对象初始化静态局部对象n; A(float a)x=a; y=0; cout初始化全局对象初始化全局对象n; A() cout“调用析构函数调用析构函数”endl; ;A a0(100.0);/定义全局对象定义全局对象void f(void) cout 进入进入f()函数函数n; A ab(10.0, 20.0);/定义局部自动对象定义局部自动对象

28、 static A a3; /初始化局部静态对象初始化局部静态对象 void main(void) cout进入进入main函数函数n;f(); f(); 初始化全局对象初始化全局对象进入进入main函数函数初始化自动局部对象初始化自动局部对象进入进入f()函数函数初始化静态局部对象初始化静态局部对象进入进入f()函数函数初始化自动局部对象初始化自动局部对象调用析构函数调用析构函数调用析构函数调用析构函数调用析构函数调用析构函数调用析构函数调用析构函数第30页/共53页第三十一页,编辑于星期六:三点 五十五分。举例:建立一个类举例:建立一个类NUM,求指定数据范围内的所有素数。,求指定数据范围

29、内的所有素数。如:如: 定义类定义类NUM的对象的对象test,查找范围为,查找范围为100200,正确,正确的输出结果:的输出结果:num=21101 103 107 109 113127 131 第31页/共53页第三十二页,编辑于星期六:三点 五十五分。动态构造及析构对象数组动态构造及析构对象数组 用用new运算符来动态生成对象数组时,自动调用构造函运算符来动态生成对象数组时,自动调用构造函数,而用数,而用delete运算符来运算符来释放释放p1所指向的对象数组所指向的对象数组占用占用的存储空间时,在指针变量的前面必须加上的存储空间时,在指针变量的前面必须加上 , 才才能将数组元素所占用

30、的空间全部释放。否则,只能将数组元素所占用的空间全部释放。否则,只释放第释放第0个元素所占用的空间。个元素所占用的空间。pa1=new A3;. delete pa1; 第32页/共53页第三十三页,编辑于星期六:三点 五十五分。class Afloat x,y;public: A(float a=0, float b=0)x=a; y=b;cout调用了构造函数调用了构造函数n; void Print(void) coutxtyendl; A() cout调用了析构函数调用了析构函数n; ;void main(void) cout进入进入main()函数函数n; A *pa1; pa1=ne

31、w A3;/开辟数组空间开辟数组空间coutn完成开辟数组空间完成开辟数组空间nn; delete pa1; /必须用必须用删除开辟的空间删除开辟的空间 cout退出退出main()函数函数n;进入进入main()函数函数调用了构造函数调用了构造函数调用了构造函数调用了构造函数调用了构造函数调用了构造函数完成开辟数组空间完成开辟数组空间调用了析构函数调用了析构函数调用了析构函数调用了析构函数调用了析构函数调用了析构函数退出退出main()函数函数第33页/共53页第三十四页,编辑于星期六:三点 五十五分。缺省的析构函数若在类的定义中没有显式地定义析构函数时,则编译器若在类的定义中没有显式地定义

32、析构函数时,则编译器自动地产生一个缺省的析构函数,其格式为:自动地产生一个缺省的析构函数,其格式为:ClassName:ClassName() ;任何对象都必须有构造函数和析构函数,但在撤消对任何对象都必须有构造函数和析构函数,但在撤消对象时,象时,要释放对象的数据成员用要释放对象的数据成员用new运算符分配的动态运算符分配的动态空间时,必须显式地定义析构函数空间时,必须显式地定义析构函数。 第34页/共53页第三十五页,编辑于星期六:三点 五十五分。实现类型转换的构造函数实现类型转换的构造函数同类型的对象可以相互赋值,相当于类中的数据成同类型的对象可以相互赋值,相当于类中的数据成员相互赋值;

33、员相互赋值;如果如果直接将数据赋给对象直接将数据赋给对象,所赋入的数据需要强制,所赋入的数据需要强制类型转换,类型转换,这种转换需要调用构造函数这种转换需要调用构造函数。第35页/共53页第三十六页,编辑于星期六:三点 五十五分。class Afloat x,y;public: A(float a,float b) x=a;y=b;cout调用构造函数调用构造函数n; A() cout调用析构函数调用析构函数n; void Print(void) coutxtyendl;void main(void) A a1(1.0, 10.0); a1.Print(); a1=A(3.0 , 30.0);

34、 a1.Print(); cout退出主函数退出主函数n;调用构造函数调用构造函数产生临时对象,产生临时对象,初始化并赋值后初始化并赋值后立即释放立即释放1 10调用构造函数调用构造函数调用析构函数调用析构函数330退出主函数退出主函数调用析构函数调用析构函数第36页/共53页第三十七页,编辑于星期六:三点 五十五分。注意:当构造函数只有一个参数时,可以用注意:当构造函数只有一个参数时,可以用= 强制赋值强制赋值。class Bfloat x;public: B(float a) x=a; cout调用构造函数调用构造函数n; B() cout调用析构函数调用析构函数n; void Print

35、(void) coutxendl; ;void main(void)B b1(1.0) ;b1.Print(); B b2=100; b2.Print(); b1=10; b1.Print(); cout退出主函数退出主函数n;调用构造函数调用构造函数单参数可以这样赋值单参数可以这样赋值1调用构造函数调用构造函数100调用构造函数调用构造函数调用析构函数调用析构函数10退出主函数退出主函数调用析构函数调用析构函数调用析构函数调用析构函数b1=B(10)产生一个产生一个临时对象临时对象第37页/共53页第三十八页,编辑于星期六:三点 五十五分。完成拷贝功能的构造函数完成拷贝功能的构造函数 可以在

36、定义一个对象的时候用另一个对象为其初可以在定义一个对象的时候用另一个对象为其初始化,始化,即构造函数的参数是另一个对象的引用即构造函数的参数是另一个对象的引用,这种这种构造函数常为完成拷贝功能的构造函数。构造函数常为完成拷贝功能的构造函数。完成拷贝功能的构造函数的一般格式为:完成拷贝功能的构造函数的一般格式为:ClassName:ClassName(ClassName &)./ 函数体完成对应数据成员的赋值函数体完成对应数据成员的赋值第38页/共53页第三十九页,编辑于星期六:三点 五十五分。class Afloat x,y;public: A(float a=0, float b=0)x=a

37、; y=b; A(A &a) x=a.x; y=a.y;;void main(void) A a1(1.0,2.0); A a2(a1);形参形参必须必须是同类型对象的引用是同类型对象的引用实参是同类型的对象实参是同类型的对象第39页/共53页第四十页,编辑于星期六:三点 五十五分。class Afloat x,y;public: A(float a=0, float b=0)x=a; y=b;cout调用了构造函数调用了构造函数n; A(A &a) x=a.x;y=a.y;cout“调用了完成拷贝功能的构造函数调用了完成拷贝功能的构造函数n”; void Print(void) coutxt

38、yendl; A() cout调用了析构函数调用了析构函数n; ;void main(void) A a1(1.0,2.0); A a2(a1); a1.Print(); a2.Print();调用了构造函数调用了构造函数调用了完成拷贝功能的构造函调用了完成拷贝功能的构造函数数1212调用了析构函数调用了析构函数调用了析构函数调用了析构函数用已有的对象中的数据为新创建的对象赋值用已有的对象中的数据为新创建的对象赋值第40页/共53页第四十一页,编辑于星期六:三点 五十五分。如果如果没有定义没有定义完成拷贝功能的构造函数,编译器完成拷贝功能的构造函数,编译器自动自动生成一个隐含的完成拷贝功能的构

39、造函数生成一个隐含的完成拷贝功能的构造函数,依次完成类中对应数据成员的拷贝依次完成类中对应数据成员的拷贝。 A:A(A &a) x=a.x; y=a.y; 隐含的构隐含的构造函数造函数第41页/共53页第四十二页,编辑于星期六:三点 五十五分。class Afloat x,y;public: A(float a=0, float b=0)x=a; y=b;cout调用了构造函数调用了构造函数n; void Print(void) coutxtyendl; A() cout调用了析构函数调用了析构函数n; ;void main(void) A a1(1.0,2.0); A a2(a1); A a

40、3=a1;/可以这样赋值可以这样赋值 a1.Print(); a2.Print(); a3.Print();调用了构造函数调用了构造函数121212调用了析构函数调用了析构函数调用了析构函数调用了析构函数调用了析构函数调用了析构函数隐含了拷贝隐含了拷贝的构造函数的构造函数第42页/共53页第四十三页,编辑于星期六:三点 五十五分。由编译器为每个类产生的这种隐含的完成拷贝功由编译器为每个类产生的这种隐含的完成拷贝功能的构造函数,依次完成类中对应数据成员的拷能的构造函数,依次完成类中对应数据成员的拷贝。贝。但是,当类中的数据成员中使用但是,当类中的数据成员中使用new运算符,运算符,动态地申请存储

41、空间进行赋初值时,必须在动态地申请存储空间进行赋初值时,必须在类中类中显式显式地定义一个完成拷贝功能的构造函数,地定义一个完成拷贝功能的构造函数,以便正确实现数据成员的复制以便正确实现数据成员的复制。第43页/共53页第四十四页,编辑于星期六:三点 五十五分。class Str int Length; char *Sp;public: Str(char *string) if(string)Length=strlen(string); Sp=new charLength+1; strcpy(Sp,string); else Sp=0; void Show(void)coutSpendl;Str

42、()if(Sp) delete Sp;void main(void)Str s1(Study C+);Str s2(s1);s1.Show ();s2.Show ();隐含的拷贝构造函数为:隐含的拷贝构造函数为:Str:Str(Str &s)Length=s.Length;Sp=s.Sp;“Study C+”s1.Sps2.Spnew开辟的开辟的空间空间同一空间释放两次,造成运行错同一空间释放两次,造成运行错误。误。第44页/共53页第四十五页,编辑于星期六:三点 五十五分。在这种情况下,在这种情况下,必须必须要定义完成拷贝功能的构造函数。要定义完成拷贝功能的构造函数。Str:Str(Str

43、&s) if(s.Sp)Length=s.Length ;Sp=new charLength+1;strcpy(Sp,s.Sp);else Sp=0; Str s2(s1);“Study C+”s1.Sp原来原来s1开辟开辟的空间的空间“Study C+”s2.Sp拷贝函数中用拷贝函数中用new开辟的空间开辟的空间第45页/共53页第四十六页,编辑于星期六:三点 五十五分。构造函数与对象成员构造函数与对象成员对类对类A的对象初始化的同时还要对其的对象初始化的同时还要对其成员数据成员数据类类B的对象的对象进行初始化,所以,进行初始化,所以,类类A的构造函的构造函数中要调用类数中要调用类B的构造函

44、数的构造函数。class B .;class A int x , y; B b1,b2; ;在类在类A中包含中包含类类B的对象的对象第46页/共53页第四十七页,编辑于星期六:三点 五十五分。class A float x,y;public: A(int a,int b)x=a;y=b; void Show() cout x=xty=yn; ;class Cfloat z; A a1;/类类C的数据成员为类的数据成员为类A 的对象的对象a1public: C(int a,int b,int c):a1(b, c) z=a;/类类C的对象初始化的对象初始化 void Show()cout “z=

45、an; a1.Show(); ;void main(void)C c1(1, 2, 3 );/对类对类C的对象初始化的对象初始化c1.Show();在类在类C中调用类中调用类A的成员函数的成员函数利用类利用类A的构造函数对类的构造函数对类A的对象初始化的对象初始化第47页/共53页第四十八页,编辑于星期六:三点 五十五分。xyA()Show()za1.xa1.ya1.A()a1.Show()C( )Show( )a1ACa1(b, c)第48页/共53页第四十九页,编辑于星期六:三点 五十五分。ClassName:ClassName(args):c1(args1),.,cn(agrsn). /

46、对其它成员的初始化对其它成员的初始化 初始化初始化对象成员的参数(实参)可以是表达式对象成员的参数(实参)可以是表达式。,也可。,也可以仅对部分对象成员进行初始化。以仅对部分对象成员进行初始化。第49页/共53页第五十页,编辑于星期六:三点 五十五分。class A float x,y;public: A(int a,int b) x=a;y=b;void Show() cout x=xty=yn; ;class Bfloat x1,y1;public:B(int a, int b) x1=a; y1=b; void Show() cout“x1=“x1t“y=“yn;class Cfloat

47、 z; A a1; B b1;public: C(int a,int b,int c,int d, int e):a1(a+b, c) ,b1(a,d) z=e; void Show()cout “z=an;a1.Show();b1.Show(); ;void main(void)C c1(1, 2, 3 ,4,5);/对类对类C的对象初始化的对象初始化 对象初始化的参数可以是表达式对象初始化的参数可以是表达式第50页/共53页第五十一页,编辑于星期六:三点 五十五分。对对象成员的构造函数的对对象成员的构造函数的调用顺序调用顺序取决于这些取决于这些对象成员在类中说明的顺序对象成员在类中说明的顺

48、序,与它们在成员初始,与它们在成员初始化列表中的顺序无关。化列表中的顺序无关。当建立类当建立类ClassName的对象时,先调用各个对象的对象时,先调用各个对象成员的构造函数,初始化相应的对象成员,然后成员的构造函数,初始化相应的对象成员,然后才执行类才执行类ClassName的构造函数,初始化类的构造函数,初始化类ClassName中的其它成员。中的其它成员。析构函数的调用顺析构函数的调用顺序与构造函数正好相反。序与构造函数正好相反。第51页/共53页第五十二页,编辑于星期六:三点 五十五分。class Afloat x;public: A(int a) x=a; cout“调用了调用了A的

49、构造函数的构造函数n”; A()cout“调用了调用了A的析构函数的析构函数n”;class Bfloat y;public: B(int a) y=a; cout“调用了调用了B的构造函数的构造函数n”; B()cout“调用了调用了B的析构函数的析构函数n”;class Cfloat z; B b1; A a1;public: C(int a,int b,int c): a1(a),b1(b)z=c;cout“调用了调用了C的构造函数的构造函数n”; C()cout“调用了调用了C的析构函数的析构函数n”;void main(void) C c1(1,2,3); 调用了调用了B的构造函数的构造函数调用了调用了A的构造函数的构造函数调用了调用了C的构造函数的构造函数调用了调用了C的析构函数的析构函数调用了调用了A的析构函数的析构函数调用了调用了B的析构函数的析构函数第52页/共53页第五十三页,编辑于星期六:三点 五十五分。

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

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

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


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