c构造函数与析构函数.pptx

上传人:莉*** 文档编号:73645700 上传时间:2023-02-21 格式:PPTX 页数:53 大小:251.08KB
返回 下载 相关 举报
c构造函数与析构函数.pptx_第1页
第1页 / 共53页
c构造函数与析构函数.pptx_第2页
第2页 / 共53页
点击查看更多>>
资源描述

《c构造函数与析构函数.pptx》由会员分享,可在线阅读,更多相关《c构造函数与析构函数.pptx(53页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、构造函数和析构函数是在类体中说明的两种特殊的成员函数。构造函数是在创建对象时,使用给定的值来将对象初始化。析构函数的功能正好相反,是在系统释放对象前,对对象做一些善后工作。第1页/共53页构造函数是类的成员函数,系统约定构造函数名必须与类名相同。构造函数提供了初始化对象的一种简单的方法。构造函数可以带参数、可以重载,同时没有返回值。第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

2、(void)coutx=xty=yendl;void main(void)A a1(2.0,3.0);/定义时调用构造函数初始化A a2(1.0,2.0);a2.Set(10.0,20.0);/利用成员函数重新为对象赋值 a1.Print();a2.Print();第3页/共53页对构造函数,说明以下几点:1.构造函数的函数名必须与类名相同。构造函数的主要作用是完成初始化对象的数据成员以及其它的初始化工作。2.在定义构造函数时,不能指定函数返回值的类型,也不能指定为void类型。3.一个类可以定义若干个构造函数。当定义多个构造函数时,必须满足函数重载的原则。第4页/共53页4.构造函数可以指定

3、参数的缺省值。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();002010

4、37带缺省参数的构造函数不带参数的构造函数每一个对象必须要有相应的构造函数第6页/共53页每一个对象必须要有相应的构造函数若没有显式定义构造函数,系统默认缺省的构造函数。class Afloat x,y;public:A()void Print(void)coutxtyendl;隐含的缺省的构造函数A a1,a2;只允许这样定义对象对象开辟了空间,但没有初始化第7页/共53页对局部对象,静态对象,全局对象的初始化对于局部对象,每次定义对象时,都要调用构造函数。对于静态对象,是在首次定义对象时,调用构造函数的,且由于对象一直存在,只调用一次构造函数。对于全局对象,是在main函数执行之前调用构造

5、函数的。第8页/共53页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(float a)x=a;y=0;cout初始化全局对象n;void Print(void)c

6、outxtyendl;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()函数初始化局部静态变量进入f()函数初始化自动局部对象初始化自动局部对象第10页/共53页缺省的构造函数 在在定定义义类类时时,若若没没有有定定义义类类的的构构造造函函数数,则则编编译器译器自动自动产生一个缺省的构造函数,其格式为:产生一个缺

7、省的构造函数,其格式为:className:className()缺缺省省的的构构造造函函数数并并不不对对所所产产生生对对象象的的数数据据成成员员赋初值赋初值;即;即新产生对象的数据成员的值是不确定的。新产生对象的数据成员的值是不确定的。第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;/产生对象时,自动调

8、用缺省的构造函数,不赋值a1.Set(2.0,4.0);couta1:;a1.Print();couta1.sum=a1.Sum()endl;a2.Print();/打印随机值第12页/共53页关于缺省的构造函数,说明以下几点:1、在定义类时,只要显式定义了一个类的构造函数,则编译器就不产生缺省的构造函数2、所有的对象在定义时,必须调用构造函数不存在没有构造函数的对象!第13页/共53页class Afloat x,y;public:A(float a,float b)x=a;y=b;void Print(void)coutxtyendl;void main(void)A a1;A a2(3.

9、0,30.0);显式定义了构造函数,不产生缺省的构造函数error,定义时,没有构造函数可供调用第14页/共53页3、在类中,若定义了没有参数的构造函数,或各参数均有缺省值的构造函数也称为缺省的构造函数,缺省的构造函数只能有一个。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);两个函数均为缺省的构造函数两个构造函

10、数均可供调用,构造函数不唯一第16页/共53页构造函数与new运算符 可以使用可以使用new运算符来运算符来动态地动态地建立对象。建立建立对象。建立时时要自动调用构造函数要自动调用构造函数,以便完成初始化对象的数,以便完成初始化对象的数据成员。最后返回这个动态对象的起始地址。据成员。最后返回这个动态对象的起始地址。用用new运算符产生的动态对象,在不再使用这运算符产生的动态对象,在不再使用这种对象时,必须用种对象时,必须用delete运算符来释放对象所占用运算符来释放对象所占用的存储空间。的存储空间。用用new建立类的对象时,可以使用参数初始化建立类的对象时,可以使用参数初始化动态空间。动态空

11、间。第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释放空间350 0第18页/共53页析构函数 析构函数的作用与构造函数正好相反,析构函数的作用与构造函数正好相反,是在对象的生是在对象的生命期结束时,释放系统为对象所分配的空间,即要撤消一命期结束时,释放系统为对象所分配的空间,即要撤消一个对象。个对象。析构函数也是类的成员函数,定义

12、析构函数的格式为:ClassName:ClassName()./函数体;第19页/共53页析构 函数的特点如下:1、析构函数是成员函数,函数体可写在类体内,也可写在类体外。2、析构函数是一个特殊的成员函数,函数名必须与类名相同,并在其前面加上字符“”,以便和构造函数名相区别。3、析构函数不能带有任何参数,不能有返回值,不指定函数类型。第20页/共53页在程序的执行过程中,当遇到某一对象的生存期结束时,系统自动调用析构函数,然后再收回为对象分配的存储空间。4、一个类中,只能定义一个析构函数,析构函数不允许重载。5、析构函数是在撤消对象时由系统自动调用的。第21页/共53页class Afloat

13、 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;调用缺省的构造函数调用非缺省的构造函数退出主函数调用析构函数调用析构函数第22页/共53页 在在程程序序的的执执行行过过程程中中,对对象象如如果果用用new运运算算符符开开辟辟了了空空间间,则则在在类类中中应应该该定定义义一一个个析析构构函函数数,并并在在析析构

14、构函函数数中中使使用用delete删删除除由由new分分配配的的内内存存空空间间。因因为为在在撤撤消消对对象象时时,系系统统自自动动收收回回为为对对象象所所分分配配的的存存储储空空间间,而而不不能能自自动动收收回回由由new分分配配的的动动态态存存储储空间。空间。第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;St

15、r()if(Sp)delete Sp;void main(void)Str s1(Study C+);s1.Show();在构造函数中将成员数据指针指向动态开辟的内存用初值为开辟的内存赋值析构函数,当释放对象时收回用new开辟的空间第24页/共53页Study C+0stringLength=strlen(string);Sp=new charLength+1;Spnew开辟的空间strcpy(Sp,string);Study C+0第25页/共53页用用new运算符为对象分配动态存储空间时,调运算符为对象分配动态存储空间时,调用了构造函数,用用了构造函数,用delete删除这个空间时,调用了

16、删除这个空间时,调用了析构函数。析构函数。当使用运算符当使用运算符delete删除一个由删除一个由new动动态产生的对象时,它首先调用该对象的析构函数,态产生的对象时,它首先调用该对象的析构函数,然后再释放这个对象占用的内存空间然后再释放这个对象占用的内存空间。可以用new运算符为对象分配存储空间,如:A *p;p=new A;这时必须用delete才能释放这一空间。delete p;第26页/共53页class Afloat x,y;public:A(float a,float b)x=a;y=b;cout调用了构造函数n;void Print(void)coutxtyendl;A()cou

17、t调用了析构函数n;void main(void)coutPrint();delete pa1;/调用析构函数 cout退出main()函数n;进入main()函数调用了构造函数35调用了析构函数退出main()函数第27页/共53页不同存储类型的对象调用构造函数及析构函数 1、对于全局定义的对象(在函数外定义的对象),在程序开始执行时,调用构造函数;到程序结束时,调用析构函数。2、对于局部定义的对象(在函数内定义的对象),当程序执行到定义对象的地方时,调用构造函数;在退出对象的作用域时,调用析构函数。3、用static定义的局部对象,在首次到达对象的定义时调用构造函数;到程序结束时,调用析构

18、函数第28页/共53页 4、对于用new运算符动态生成的对象,在产生对象时调用构造函数,只有使用delete运算符来释放对象时,才调用析构函数。若不使用delete来撤消动态生成的对象,程序结束时,对象仍存在,并占用相应的存储空间,即系统不能自动地调用析构函数来撤消动态生成的对象。第29页/共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

19、.0);/定义全局对象void f(void)cout 进入f()函数n;A ab(10.0,20.0);/定义局部自动对象 static A a3;/初始化局部静态对象 void main(void)cout进入main函数n;f();f();初始化全局对象进入main函数初始化自动局部对象进入f()函数初始化静态局部对象进入f()函数初始化自动局部对象调用析构函数调用析构函数调用析构函数调用析构函数第30页/共53页举例:建立一个类NUM,求指定数据范围内的所有素数。如:定义类NUM的对象test,查找范围为100200,正确的输出结果:num=21101 103 107 109 1131

20、27 131 第31页/共53页动态构造及析构对象数组 用new运算符来动态生成对象数组时,自动调用构造函数,而用delete运算符来释放p1所指向的对象数组占用的存储空间时,在指针变量的前面必须加上,才能将数组元素所占用的空间全部释放。否则,只释放第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进

21、入main()函数n;A *pa1;pa1=new A3;/开辟数组空间coutn完成开辟数组空间nn;delete pa1;/必须用删除开辟的空间 cout退出main()函数n;进入main()函数调用了构造函数调用了构造函数调用了构造函数完成开辟数组空间调用了析构函数调用了析构函数调用了析构函数退出main()函数第33页/共53页缺省的析构函数若在类的定义中没有显式地定义析构函数时,则编译器自动地产生一个缺省的析构函数,其格式为:ClassName:ClassName();任何对象都必须有构造函数和析构函数,但在撤消对象时,要释放对象的数据成员用new运算符分配的动态空间时,必须显式地

22、定义析构函数。第34页/共53页实现类型转换的构造函数同类型的对象可以相互赋值,相当于类中的数据成员相互赋值;如果直接将数据赋给对象,所赋入的数据需要强制类型转换,这种转换需要调用构造函数。第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);a1.Print();cout退出主函数n;调用构造函数调用构造函数产

23、生临时对象,初始化并赋值后立即释放1 10调用构造函数调用析构函数330退出主函数调用析构函数第36页/共53页注意:当构造函数只有一个参数时,可以用=强制赋值。class Bfloat x;public:B(float a)x=a;cout调用构造函数n;B()cout调用析构函数n;void Print(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退出主函数调用

24、析构函数调用析构函数b1=B(10)产生一个临时对象第37页/共53页完成拷贝功能的构造函数 可以在定义一个对象的时候用另一个对象为其初始化,即构造函数的参数是另一个对象的引用,这种构造函数常为完成拷贝功能的构造函数。完成拷贝功能的构造函数的一般格式为:ClassName:ClassName(ClassName&)./函数体完成对应数据成员的赋值第38页/共53页class Afloat x,y;public:A(float a=0,float b=0)x=a;y=b;A(A&a)x=a.x;y=a.y;;void main(void)A a1(1.0,2.0);A a2(a1);形参必须是同

25、类型对象的引用实参是同类型的对象第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)coutxtyendl;A()cout调用了析构函数n;void main(void)A a1(1.0,2.0);A a2(a1);a1.Print();a2.Print();调用了构造函数调用了构造函数调用了完成拷贝功能的构造函数调用了完成拷贝功能的构造函数1212调用了析构函数调用了析构函数调用了析

26、构函数调用了析构函数用已有的对象中的数据为新创建的对象赋值第40页/共53页如果没有定义完成拷贝功能的构造函数,编译器自动生成一个隐含的完成拷贝功能的构造函数,依次完成类中对应数据成员的拷贝。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 a3=a1;/可以这样赋值 a1.

27、Print();a2.Print();a3.Print();调用了构造函数121212调用了析构函数调用了析构函数调用了析构函数隐含了拷贝的构造函数第42页/共53页由编译器为每个类产生的这种隐含的完成拷贝功能的构造函数,依次完成类中对应数据成员的拷贝。但是,当类中的数据成员中使用new运算符,动态地申请存储空间进行赋初值时,必须在类中显式地定义一个完成拷贝功能的构造函数,以便正确实现数据成员的复制。第43页/共53页class Str int Length;char *Sp;public:Str(char*string)if(string)Length=strlen(string);Sp=n

28、ew charLength+1;strcpy(Sp,string);else Sp=0;void Show(void)coutSpendl;Str()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&s)if(s.S

29、p)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的构造函数。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

30、;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=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页ClassN

31、ame:ClassName(args):c1(args1),.,cn(agrsn)./对其它成员的初始化 初始化对象成员的参数(实参)可以是表达式。,也可以仅对部分对象成员进行初始化。第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 z;A a1;B b1;public:C(int a,int b,i

32、nt 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页对对象成员的构造函数的调用顺序取决于这些对象成员在类中说明的顺序,与它们在成员初始化列表中的顺序无关。当建立类ClassName的对象时,先调用各个对象成员的构造函数,初始化相应的对象成员,然后才执行类ClassName的构造函数,初始化类ClassName中的其它成员。析构函数的调用顺序与构造函数正好相反。

33、第51页/共53页class Afloat x;public:A(int a)x=a;cout“调用了A的构造函数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页感谢您的观看!第53页/共53页

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 应用文书 > PPT文档

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

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁