类和对象的进一步讨论.ppt
《类和对象的进一步讨论.ppt》由会员分享,可在线阅读,更多相关《类和对象的进一步讨论.ppt(109页珍藏版)》请在三一办公上搜索。
1、第三章 关于类和对象的进一步讨论,构造函数和析构函数是在类体中说明的两种特殊的成员函数。,构造函数是在创建对象时,使用给定的值来将对象初始化。,析构函数的功能正好相反,是在系统释放对象前,对对象做一些善后工作。,构造函数是类的成员函数,系统约定构造函数名必须与类名相同。构造函数提供了初始化对象的一种简单的方法。构造函数自动执行。,构造函数可以带参数、可以重载,同时没有返回值。构造函数不具有任何类型,不要用void说明。,例3.1 70页Time类的构造函数Timeclass Timeprivate:int hour,mimute,sec;public:Time()hour=0;minute=0
2、;sec=0;/构造函数,初始化对象 void set_time();/函数声明 void show_time();,对构造函数,说明以下几点:1.构造函数的函数名必须与类名相同。构造函数的主要作用是完成初始化对象的数据成员以及其它的初始化工作。2.在定义构造函数时,不能指定函数返回值的类型,也不能指定为void类型。3.一个类可以定义若干个构造函数。当定义多个构造函数时,必须满足函数重载的原则。,4.构造函数可以指定参数的缺省值。,5.若定义的类要说明(产生,建立)该类的对象时,构造函数必须是公有的成员函数。如果定义的类仅用于派生其它类(不直接产生该类型的对象)时,则可将构造函数定义为保护的
3、成员函数。6.构造函数不需用户调用,也不能被用户调用,是系统自动调用的。例如:t1.Time();/非法,7.如果用户没有定义构造函数,系统会自动生成一个构造函数。由于构造函数属于类的成员函数,它对私有数据成员、保护的数据成员和公有的数据成员均能进行初始化。,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
4、,3.0);/定义时调用构造函数初始化A a2(1.0,2.0);a2.Set(10.0,20.0);/利用成员函数重新为对象赋值 a1.Print();a2.Print();,例子3.2 72页 长方柱Box类的构造函数class Boxint height,width,length;public:Box(int,int,int);/声明带参数的构造函数 int volume()return(height*width*length;Box:Box(int h,int w,int len)height=h;width=w;length=len;,class Afloat x,y;public:
5、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();,00201037,带缺省参数的构造函数,不带参数的构造函数,每一个对象必须要有相应的构造函数,每一个对象必须要有相应的构造函数,若没有显式定义构造函数,系统默认缺省的构造函数。,class Afloat x,y;public:A()void Print(void)coutxtyendl;,隐含的缺省的构造函数,A
6、 a1,a2;,只允许这样定义对象,对象开辟了空间,但没有初始化,对局部对象,静态对象,全局对象的初始化对于局部对象,每次定义对象时,都要调用构造函数。对于静态对象,是在首次定义对象时,调用构造函数的,且由于对象一直存在,只调用一次构造函数。对于全局对象,是在main函数执行之前调用构造函数的。,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();,1,2,2,2,class
7、 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)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函
8、数,初始化自动局部对象,进入f()函数,初始化局部静态变量,进入f()函数,初始化自动局部对象,初始化自动局部对象,缺省的构造函数,在定义类时,若没有定义类的构造函数,则编译器自动产生一个缺省的构造函数,其格式为:className:className()缺省的构造函数并不对所产生对象的数据成员赋初值;即新产生对象的数据成员的值是不确定的。,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
9、=xty=yendl;void main(void)A a1,a2;/产生对象时,自动调用缺省的构造函数,不赋值a1.Set(2.0,4.0);couta1:;a1.Print();couta1.sum=a1.Sum()endl;a2.Print();/打印随机值,关于缺省的构造函数,说明以下几点:1、在定义类时,只要显式定义了一个类的构造函数,则编译器就不产生缺省的构造函数,2、所有的对象在定义时,必须调用构造函数,不存在没有构造函数的对象!,class Afloat x,y;public:A(float a,float b)x=a;y=b;void Print(void)coutxtyen
10、dl;void main(void)A a1;A a2(3.0,30.0);,显式定义了构造函数,不产生缺省的构造函数,error,定义时,没有构造函数可供调用,3、在类中,若定义了没有参数的构造函数,或各参数均有缺省值的构造函数也称为缺省的构造函数,缺省的构造函数只能有一个。,4、产生对象时,系统必定要调用构造函数。所以任一对象的构造函数必须唯一。,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);,
11、两个函数均为缺省的构造函数,两个构造函数均可供调用,构造函数不唯一,用参数初始化表对数据成员初始化:,Box:Box(int h,int w,int len)height=h;width=w;length=len;等同与下面的程序:Box:Box(int h,int w,int len):height(h),width(w),length(len)即在原来函数”)”后加一个冒号”:”,然后列出参数的初始化表。,析构函数,析构函数的作用与构造函数正好相反,是在对象的生命期结束时,释放系统为对象所分配的空间,即要撤消一个对象。,析构函数也是类的成员函数,定义析构函数的格式为:ClassName:C
12、lassName()./函数体;,析构 函数的特点如下:1、析构函数是成员函数,函数体可写在类体内,也可写在类体外。,2、析构函数是一个特殊的成员函数,函数名必须与类名相同,并在其前面加上字符“”,以便和构造函数名相区别。,3、析构函数不能带有任何参数,不能有返回值,不指定函数类型。,在程序的执行过程中,当遇到某一对象的生存期结束时,系统自动调用析构函数,然后再收回为对象分配的存储空间。,4、一个类中,只能定义一个析构函数,析构函数不允许重载。,5、析构函数是在撤消对象时由系统自动调用的。,class Afloat x,y;public:A(float a,float b)x=a;y=b;co
13、ut调用非缺省的构造函数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;,调用缺省的构造函数,调用非缺省的构造函数,退出主函数,调用析构函数,调用析构函数,例子3.5 7880页 student类 class Student Student()/定义析构函数 cout“Destructor called.”endl;析构次序与构造次序相反。见80页的执行结果。80页图3.1,构造函数与new运算符,可以使用ne
14、w运算符来动态地建立对象。建立时要自动调用构造函数,以便完成初始化对象的数据成员。最后返回这个动态对象的起始地址。,用new运算符产生的动态对象,在不再使用这种对象时,必须用delete运算符来释放对象所占用的存储空间。,用new建立类的对象时,可以使用参数初始化动态空间。,class Afloat x,y;public:A(float a,float b)x=a;y=b;A()x=0;y=0;void Print(void)coutPrint();pa2-Print();delete pa1;/用delete释放空间 delete pa2;/用delete释放空间,500,在程序的执行过程中
15、,对象如果用new运算符开辟了空间,则在类中应该定义一个析构函数,并在析构函数中使用delete删除由new分配的内存空间。因为在撤消对象时,系统自动收回为对象所分配的存储空间,而不能自动收回由new分配的动态存储空间。,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(v
16、oid)Str s1(Study C+);s1.Show();,在构造函数中将成员数据指针指向动态开辟的内存,用初值为开辟的内存赋值,析构函数,当释放对象时收回用new开辟的空间,string,Length=strlen(string);,Sp=new charLength+1;,Sp,new开辟的空间,strcpy(Sp,string);,用new运算符为对象分配动态存储空间时,调用了构造函数,用delete删除这个空间时,调用了析构函数。当使用运算符delete删除一个由new动态产生的对象时,它首先调用该对象的析构函数,然后再释放这个对象占用的内存空间。,可以用new运算符为对象分配存储
17、空间,如:,A*p;p=new A;,这时必须用delete才能释放这一空间。,delete p;,class Afloat x,y;public:A(float a,float b)x=a;y=b;coutPrint();delete pa1;/调用析构函数 cout退出main()函数n;,进入main()函数,调用了构造函数,35,调用了析构函数,退出main()函数,不同存储类型的对象调用构造函数及析构函数,1、对于全局定义的对象(在函数外定义的对象),在程序开始执行时,调用构造函数;到程序结束时,调用析构函数。,2、对于局部定义的对象(在函数内定义的对象),当程序执行到定义对象的地方
18、时,调用构造函数;在退出对象的作用域时,调用析构函数。,3、用static定义的局部对象,在首次到达对象的定义时调用构造函数;到程序结束时,调用析构函数,4、对于用new运算符动态生成的对象,在产生对象时调用构造函数,只有使用delete运算符来释放对象时,才调用析构函数。若不使用delete来撤消动态生成的对象,程序结束时,对象仍存在,并占用相应的存储空间,即系统不能自动地调用析构函数来撤消动态生成的对象。,class Afloat x,y;public:A(float a,float b)x=a;y=b;cout初始化自动局部对象n;A()x=0;y=0;cout初始化静态局部对象n;A(
19、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);/定义局部自动对象 static A a3;/初始化局部静态对象 void main(void)cout进入main函数n;f();f();,初始化全局对象,进入main函数,初始化自动局部对象,进入f()函数,初始化静态局部对象,进入f()函数,初始化自动局部对象,调用析构函数,调用析构函数,调用析构函数,调用析构函数,举例:建立一个类NUM,求指定数据范围内的所有素数。如:
20、定义类NUM的对象test,查找范围为100200,正确的输出结果:num=21101 103 107 109 113127 131,动态构造及析构对象数组,用new运算符来动态生成对象数组时,自动调用构造函数,而用delete运算符来释放p1所指向的对象数组占用的存储空间时,在指针变量的前面必须加上,才能将数组元素所占用的空间全部释放。否则,只释放第0个元素所占用的空间。,pa1=new A3;.delete pa1;,class Afloat x,y;public:A(float a=0,float b=0)x=a;y=b;cout调用了构造函数n;void Print(void)cout
21、xtyendl;A()cout调用了析构函数n;void main(void)cout进入main()函数n;A*pa1;pa1=new A3;/开辟数组空间coutn完成开辟数组空间nn;delete pa1;/必须用删除开辟的空间 cout退出main()函数n;,进入main()函数,调用了构造函数,调用了构造函数,调用了构造函数,完成开辟数组空间,调用了析构函数,调用了析构函数,调用了析构函数,退出main()函数,缺省的析构函数,若在类的定义中没有显式地定义析构函数时,则编译器自动地产生一个缺省的析构函数,其格式为:ClassName:ClassName();,任何对象都必须有构造函
22、数和析构函数,但在撤消对象时,要释放对象的数据成员用new运算符分配的动态空间时,必须显式地定义析构函数。,实现类型转换的构造函数,同类型的对象可以相互赋值,相当于类中的数据成员相互赋值;如果直接将数据赋给对象,所赋入的数据需要强制类型转换,这种转换需要调用构造函数。,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.P
23、rint();cout退出主函数n;,调用构造函数,产生临时对象,初始化并赋值后立即释放,1 10,调用构造函数,调用析构函数,330,退出主函数,调用析构函数,注意:当构造函数只有一个参数时,可以用=强制赋值。,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,
24、调用构造函数,100,调用构造函数,调用析构函数,10,退出主函数,调用析构函数,调用析构函数,b1=B(10),产生一个临时对象,完成拷贝功能的构造函数,可以在定义一个对象的时候用另一个对象为其初始化,即构造函数的参数是另一个对象的引用,这种构造函数常为完成拷贝功能的构造函数。,完成拷贝功能的构造函数的一般格式为:ClassName:ClassName(ClassName&)./函数体完成对应数据成员的赋值,class Afloat x,y;public:A(float a=0,float b=0)x=a;y=b;A(A;,void main(void)A a1(1.0,2.0);A a2(
25、a1);,形参必须是同类型对象的引用,实参是同类型的对象,class Afloat x,y;public:A(float a=0,float b=0)x=a;y=b;cout调用了构造函数n;A(A,调用了构造函数调用了完成拷贝功能的构造函数1212调用了析构函数调用了析构函数,用已有的对象中的数据为新创建的对象赋值,如果没有定义完成拷贝功能的构造函数,编译器自动生成一个隐含的完成拷贝功能的构造函数,依次完成类中对应数据成员的拷贝。,A:A(A,隐含的构造函数,class Afloat x,y;public:A(float a=0,float b=0)x=a;y=b;cout调用了构造函数n;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 对象 进一步 讨论

链接地址:https://www.31ppt.com/p-6329513.html