资源预览内容
第1页 / 共53页
第2页 / 共53页
第3页 / 共53页
第4页 / 共53页
第5页 / 共53页
第6页 / 共53页
第7页 / 共53页
第8页 / 共53页
第9页 / 共53页
第10页 / 共53页
亲,该文档总共53页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第十章 构造函数和析构函数构造函数和析构函数是在类体中说明的两种特殊的成员函数。构造函数是在创建对象时,使用给定的值来将对象初始化。析构函数的功能正好相反,是在系统释放对 象前,对对象做一些善后工作。构造函数是类的成员函数,系统约定构造函数名必须与类名相同。构造函数提供了初始化对象的一种简单的方法。构造函数可以带参数、可以重载,同时没有返回值。class A float 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) coutPrint();pa2-Print();delete pa1; /用delete释放空间delete pa2; /用delete释放空间 3 50 0析构函数 析构函数的作用与构造函数正好相反,是在对象的生命期结束时,释放系统为对象所分配的空间,即要撤消一个对象。析构函数也是类的成员函数,定义析构函数的格式为:ClassName:ClassName( )./ 函数体;析构 函数的特点如下:1、析构函数是成员函数,函数体可写在类体内,也可写在类体外。2、析构函数是一个特殊的成员函数,函数名必须与类名相同,并在其前面加上字符“”,以便和构造函数名相区别。3、析构函数不能带有任何参数,不能有返回值,不指定函数类型。在程序的执行过程中,当遇到某一对象的生存期结束时,系统自动调用析构函数,然后再收回为对象分配的存储空间。4、一个类中,只能定义一个析构函数,析构函数不允许重载。5、析构函数是在撤消对象时由系统自动调用的。class A float x,y; public:A(float a,float b)x=a;y=b;coutPrint();delete pa1; /调用析构函数cout)./ 函数体完成对应数据成员的赋值class Afloat x,y;public:A(float a=0, float b=0)x=a; y=b;A(A y=a.y;;void main(void) A a1(1.0,2.0);A a2(a1);形参必须是同类型对象的引用实参是同类型的对象class A float x,y; public:A(float a=0, float b=0)x=a; y=b;cout“调用了构造函数n“;A(A 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调用了析构函数调用了析构函数用已有的对象中的数据为新创建的对象赋值如果没有定义完成拷贝功能的构造函数,编译器自动生成一个隐含的完成拷贝功能的构造函数,依次完成类中对应数据成员的拷贝。 A:A(A y=a.y;隐含的构 造函数class A float 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.Print();a2.Print();a3.Print(); 调用了构造函数121212调用了析构函数调用了析构函数调用了析构函数隐含了拷贝 的构造函数由编译器为每个类产生的这种隐含的完成拷贝功能的构造函数,依次完成类中对应数据成员的拷贝。但是,当类中的数据成员中使用new运算符,动态地申请存储空间进行赋初值时,必须在类中显式地定义一个完成拷贝功能的构造函数,以便正确实现数据成员的复制。class Strint 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()if(Sp) delete Sp; ; void main(void) Str s1(“Study C+“); Str s2(s1); s1.Show ();s2.Show (); 隐含的拷贝构造函数为:Str:Str(Str Sp=s.Sp;“Study C+”s1.Sps2.Spnew开辟 的空间同一空间释放两次,造成运 行错误。在这种情况下,必须要定义完成拷贝功能的构造函数。Str:Str(Str Sp=new charLength+1;strcpy(Sp,s.Sp);else Sp=0;Str s2(s1);“Study C+”s1.Sp原来s1开 辟的空间“Study C+”s2.Sp拷贝函数中用 new开辟的空间构造函数与对象成员对类A的对象初始化的同时还要对其成员数据类B的对象进行初始化,所以,类A的构造函数中要调用类B的构造函数。class B.;class Aint x , y;B b1,b2; ;在类A中包含 类B的对象class A float x,y; public: A(int a,int b)x=a;y=b;void Show() cout “x=“xt“y=“yn; ; class C float z;A a1;/类C的数据成员为类A 的对象a1 public: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的对象初始化xyA() Show ()z a1.x a1.y a1.A() a1.Sho w() C( ) Show( )a1ACa1(b, c)ClassName:ClassName(args):c1(args1),.,cn(agrsn). /对其它成员的初始化 初始化对象成员的参数(实参)可以是表达式。,也可以仅对部分对象成员进行初始化。class A float x,y; public: A(int a,int b) x=a;y=b; void Show() cout “x=“xt“y=“yn; ; class B float x1,y1; public:B(int a, int b) x1=a; y1=b; void Show() cout“x1=“x1t“y=“yn; ; class C float 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的对象初始化 对象初始化的参数可以是表达式对对象成员的构造函数的调用顺序取决于这些对象成员在类中说明的顺序,与它们在成员初始化列表中的顺序无关。当建立类ClassName的对象时,先调用各个对象成员的构造函数,初始化相应的对象成 员,然后才执行类ClassName的构造函数,初始化类ClassName中的其它成员。析构函数的调用顺序与构造函数正好相反。class A float x; public:A(int a) x=a; cout“调用了A的构造函数n”;A()cout“调用了A的析构函数n”; ; class B float y; public:B(int a) y=a; cout“调用了B的构造函数n”;B()cout“调用了B的析构函数n”; ; class C float 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的析构函数
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号