第十章构造函数和析构函数.ppt
《第十章构造函数和析构函数.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类:局部对象、静态对象和全局对象。 局部对象:当执行到定义对象的语句时,产生对象并调用构造函数;当执行到结束局部对象的作用域时,调用析构函数后撤消该对象。 静态对象:当程序第一次执行所定义的静态对象时,产生该对象;直到程序结束时撤消该
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第十 构造 函数
链接地址:https://www.31doc.com/p-2573173.html