W10 -构造函数.ppt

上传人:hyn****60 文档编号:88376484 上传时间:2023-04-25 格式:PPT 页数:66 大小:671.50KB
返回 下载 相关 举报
W10 -构造函数.ppt_第1页
第1页 / 共66页
W10 -构造函数.ppt_第2页
第2页 / 共66页
点击查看更多>>
资源描述

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

1、10.1 构造函数构造函数10.2 析构函数析构函数10.3 拷贝构造函数拷贝构造函数10.4 拷贝函数与对象成员拷贝函数与对象成员第第10章章 构造函数和析构函数构造函数和析构函数 class Crect int left,top;public:int right,bottom;void setcoord(int,int,int,int);.;上一章的例题中曾提到对象的成员的初始化问题上一章的例题中曾提到对象的成员的初始化问题现在再回顾一下现在再回顾一下 在类在类Crect中共有中共有4个数据成员,其中个数据成员,其中 left,top 是私有成员是私有成员 right,bottom 是公有

2、成员是公有成员 公有成员可以直接用对象对它们初始化,私有成员的初始化公有成员可以直接用对象对它们初始化,私有成员的初始化则必须调用公有成员函数,并在函数体中通过访问私有成员来完成则必须调用公有成员函数,并在函数体中通过访问私有成员来完成 第第10章章 构造函数和析构函数构造函数和析构函数void Crect:setcoord(int L,int R,int T,int B)left=L;right=R;top=T;bottom=B;class Crect int left,top;public:int right,bottom;void setcoord(int,int,int,int);.;

3、void main(void)Crect r,rr;r.setcoord(100,300,50,200);这是调用成员函数,这是调用成员函数,可使公有和私有数据成员都被初始化可使公有和私有数据成员都被初始化 结果使得:结果使得:left=100 right=300 top=50 bottom=200第第10章章 构造函数和析构函数构造函数和析构函数例如例如第第10章章 构造函数和析构函数构造函数和析构函数 C+数数据据成成员员的的初初始始化化方方法法,除除上上述述方方法法之之外外,还还可可以以采采用用我我们们已已知知的的结结构构体体变变量量的的初初始始化化方方法法称称为为列列表表法法(见见例题

4、例题10.1,P218)。C c1=25,”张三张三”,77.8,99.56;列表法仅可对公有数据成员初始化列表法仅可对公有数据成员初始化.此外,此外,C+还提供了专门用作初始化的成员函数还提供了专门用作初始化的成员函数构造函数构造函数。而当某个对象的寿命到期时,它还提供了而当某个对象的寿命到期时,它还提供了一个用于释放对象所占资源的函数一个用于释放对象所占资源的函数析构函数析构函数。本章将分别介绍这两个函数。本章将分别介绍这两个函数。第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class Crect int left,top,right,bottom;pu

5、blic:Crect(int L,int R,int T,int B)left=L;right=R;top=T;bottom=B;.;现在把上例中现在把上例中4个数据成员都改成私有成员个数据成员都改成私有成员构造函数是类中的一个特殊的成员函数构造函数是类中的一个特殊的成员函数第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class Crect int left,top,right,bottom;public:Crect(int L,int R,int T,int B)left=L;right=R;top=T;bottom=B;.;它的特殊性表现为它的特殊性表现

6、为:构造函数没有自己的函数名构造函数没有自己的函数名而是直接用类名而是直接用类名当作函数名当作函数名与其它函数不同,与其它函数不同,不能为构造函数指定返回值类型和不能为构造函数指定返回值类型和void类型类型第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class Crect int left,top,right,bottom;public:Crect(int L,int R,int T,int B)left=L;right=R;top=T;bottom=B;.;Crect()left=0;right=0;top=0;bottom=0;;一个类可以定义一个或多

7、个构造函数,多个构造函数一个类可以定义一个或多个构造函数,多个构造函数满足函数重载原则。满足函数重载原则。下面看对象如何调用构造函数下面看对象如何调用构造函数/不带参数的构造函数不带参数的构造函数第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class Crect int left,top,right,bottom;public:Crect(int L,int R,int T,int B)left=L;right=R;top=T;bottom=B;.;Crect()left=0;right=0;top=0;bottom=0;;void main(void)Cr

8、ect r,rr(10,20,30,40);定义对象定义对象r,并调用无参构造函数并调用无参构造函数 结果使得:结果使得:left=0 right=0 top=0 bottom=0第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class Crect int left,top,right,bottom;public:Crect(int L,int R,int T,int B)left=L;right=R;top=T;bottom=B;.;Crect()left=0;right=0;top=0;bottom=0;;void main(void)Crect r,rr

9、(10,20,30,40);定义对象定义对象rr,并调用带参构造函数并调用带参构造函数 结果使得:结果使得:left=10 right=20 top=30 bottom=40第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class Crect int left,top,right,bottom;public:Crect(int L,int R,int T,int B)left=L;right=R;top=T;bottom=B;.;Crect()left=0;right=0;top=0;bottom=0;;void main(void)Crect r,rr(10

10、,20,30,40);,rrr();rrr不是对象,这种格式是不是对象,这种格式是说明一个函数原型。说明一个函数原型。这个函数的返回值是这个函数的返回值是Crect类型的对象类型的对象下面在成员函数中补充一个输出函数下面在成员函数中补充一个输出函数请注意,这种形式不是调用请注意,这种形式不是调用无参构造函数无参构造函数第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class Crect int left,top,right,bottom;public:Crect(int L,int R,int T,int B)left=L;right=R;top=T;bott

11、om=B;Crect()left=0;right=0;top=0;bottom=0;;void Show()cout“left=“left“light=“light“n”;cout“top=“top“bottom=“bottom“n”;;void main(void)Crect r,rr(10,20,30,40);r.Show();对象对象r调用成员函数调用成员函数Show(),由于,由于r是通过调是通过调用无参构造函数初始化的,因此,输出结果是用无参构造函数初始化的,因此,输出结果是left=0 right=0 top=0 bottom=0第第10章章 构造函数和析构函数构造函数和析构函数

12、10.1 构造函数构造函数 class Crect int left,top,right,bottom;public:Crect(int L,int R,int T,int B)left=L;right=R;top=T;bottom=B;Crect()left=0;right=0;top=0;bottom=0;;void Show()cout“left=“left“light=“light“n”;cout“top=“top“bottom=“bottom“n”;;void main(void)Crect r,rr(10,20,30,40);r.Show();对象对象rr调用成员函数调用成员函数S

13、how(),其结果是,其结果是left=0 right=0 top=0 bottom=0rr.Show();left=10 right=20 top=30 bottom=40第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class Crect int left,top,right,bottom;public:Crect(int L,int R,int T,int B)left=L;right=R;top=T;bottom=B;Crect()left=0;right=0;top=0;bottom=0;;void Show()cout“left=“left“lig

14、ht=“light“n”;cout“top=“top“bottom=“bottom“n”;;void main(void)Crect r,rr(10,20,30,40);r.Show();注意:注意:只要在类中定义了构造函数只要在类中定义了构造函数,构造函数是由系,构造函数是由系统自动调用的。如果没有定义无参构造函数,统自动调用的。如果没有定义无参构造函数,rr.Show();这里将引起错误,因为这里将引起错误,因为r没有对应的无参构造函数可供调用没有对应的无参构造函数可供调用第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class Crect int lef

15、t,top,right,bottom;public:Crect(int L,int R,int T,int B)left=L;right=R;top=T;bottom=B;Crect()left=0;right=0;top=0;bottom=0;;void Show()cout“left=“left“light=“light“n”;cout“top=“top“bottom=“bottom“n”;;void main(void)Crect r,rr(10,20,30,40);不带参数的构造函数也是参数为缺省值的构造函数不带参数的构造函数也是参数为缺省值的构造函数此前,我们介绍过参数为缺省值的函数

16、,此前,我们介绍过参数为缺省值的函数,这种函数同样可用于构造函数,例如这种函数同样可用于构造函数,例如 Crect(int L=0,int R=0,int T=0,int B=0)left=L;right=R;top=T;bottom=B;曾记否?所谓参数为缺省值的函数曾记否?所谓参数为缺省值的函数就是给形参赋了初值的函数就是给形参赋了初值的函数第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class Crect int left,top,right,bottom;public:Crect(int L,int R,int T,int B)left=L;righ

17、t=R;top=T;bottom=B;Crect()left=0;right=0;top=0;bottom=0;;void Shouw()cout“left=“left“light=“light“n”;cout“top=“top“bottom=“bottom“n”;;void main(void)Crect r,rr(10,20,30,40);但是,本例中将发生错误!但是,本例中将发生错误!Crect(int L=0,int R=0,int T=0,int B=0)left=L;right=R;top=T;bottom=B;因此,对象因此,对象r不知道调用哪一个不知道调用哪一个这就是说,在一个

18、类中这就是说,在一个类中缺省构造函数只能有一个缺省构造函数只能有一个因为无参或者参数为缺省值的构造函因为无参或者参数为缺省值的构造函数数都都被认为是被认为是缺省构造函数缺省构造函数,它们的,它们的性质相同。性质相同。第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class Crect int left,top,right,bottom;public:Crect(int L,int R,int T,int B)left=L;right=R;top=T;bottom=B;Crect()left=0;right=0;top=0;bottom=0;;void Shou

19、w()cout“left=“left“light=“light“n”;cout“top=“top“bottom=“bottom“n”;;void main(void)Crect r,rr(10,20,30,40);Crect(int L=0,int R=0,int T=0,int B=0)left=L;right=R;top=T;bottom=B;产生对象时,系统必定调用构造函数。产生对象时,系统必定调用构造函数。如果类中如果类中没有定义没有定义构造函数时,编译器自动产生一构造函数时,编译器自动产生一个缺省的构造函数:个缺省的构造函数:第第10章章 构造函数和析构函数构造函数和析构函数 10.

20、1 构造函数构造函数 class Crect int left,top,right,bottom;public:Crect(int L,int R,int T,int B)left=L;right=R;top=T;bottom=B;Crect()left=0;right=0;top=0;bottom=0;;void Shouw()cout“left=“left“light=“light“n”;cout“top=“top“bottom=“bottom“n”;;void main(void)Crect r,rr(10,20,30,40);Crect(int L=0,int R=0,int T=0,

21、int B=0)left=L;right=R;top=T;bottom=B;Creat()此缺省构造函数的函数体为空,此缺省构造函数的函数体为空,产生对象时,尽管调用了该构产生对象时,尽管调用了该构造函数,但对象的数据成员的造函数,但对象的数据成员的值是不确定的。值是不确定的。编译器自动产生一个缺省的构造函数。编译器自动产生一个缺省的构造函数。第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class Crect int left,top,right,bottom;public:Crect(int L,int R,int T,int B)left=L;right

22、=R;top=T;bottom=B;Crect()left=0;right=0;top=0;bottom=0;;void Shouw()cout“left=“left“light=“light“n”;cout“top=“top“bottom=“bottom“n”;;Crect:Crect(int L,int R,int T,int B)left=L;right=R;top=T;bottom=B;当然,构造函数也可以只说明原型,当然,构造函数也可以只说明原型,而在类外定义函数体。例如而在类外定义函数体。例如 Crect(int L=0,int R=0,int T=0,int B=0)left=L

23、;right=R;top=T;bottom=B;.;延伸到类体之外的定义都需要延伸到类体之外的定义都需要插入:类名插入:类名+作用域运算符作用域运算符”:”第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class A int x,y;public:A(int a,int b)x=a;y=b;cout“调用带参构造函数调用带参构造函数”t;A()cout“调用缺省构造函数调用缺省构造函数”t;void Show()cout“x=”xt“y=”yShow();delete p1;下面再看用下面再看用 new 运算符动态建立对象运算符动态建立对象并调用构造函数的过程

24、并调用构造函数的过程带参和缺省构造函数带参和缺省构造函数定义类定义类A类型的指针,并用类型的指针,并用new动态分配动态分配一个对象,同时调用带参构造函数一个对象,同时调用带参构造函数第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class A int x,y;public:A(int a,int b)x=a;y=b;cout“调用带参构造函数调用带参构造函数”t;A()cout“调用缺省构造函数调用缺省构造函数”t;void Show()cout“x=”xt“y=”yShow();delete p1;定义类定义类A类型的指针,并用类型的指针,并用new动态分

25、配动态分配一个对象,同时调用带参构造函数一个对象,同时调用带参构造函数这使得私有成员分别得到这使得私有成员分别得到x=5 y=10同时执行输出同时执行输出调用带参构造函数调用带参构造函数第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class A int x,y;public:A(int a,int b)x=a;y=b;cout“调用带参构造函数调用带参构造函数”t;A()cout“调用缺省构造函数调用缺省构造函数”t;void Show()cout“x=”xt“y=”yShow();delete p1;动态对象调用函数动态对象调用函数输出私有成员的数据输出私

26、有成员的数据调用带参构造函数调用带参构造函数X=5 y=10不再使用时应释放空间不再使用时应释放空间第第10章章 构造函数和析构函数构造函数和析构函数 10.1 构造函数构造函数 class A int x,y;public:A(int a,int b)x=a;y=b;cout“调用带参构造函数调用带参构造函数”t;A()cout“调用缺省构造函数调用缺省构造函数”t;void Show()cout“x=”xt“y=”yShow();delete p1;A*p2=new A;p2-Show();delete p2;调用缺省构造函数调用缺省构造函数由于被调的缺省构造函由于被调的缺省构造函数没有数

27、据初始化,数没有数据初始化,因此,调用输出函数时因此,调用输出函数时输出结果是不确定的。输出结果是不确定的。调用缺省构造函数调用缺省构造函数小结小结构造函数不同于普通成员函数构造函数不同于普通成员函数u在对象产生时承担初始化职能。在对象产生时承担初始化职能。u其函数名为类名,且无返回值类型。其函数名为类名,且无返回值类型。u生成对象时由系统自动调用。生成对象时由系统自动调用。u无显式定义时,由编译器自动产生缺省构造函数。无显式定义时,由编译器自动产生缺省构造函数。u即:对象的生成离不开构造函数。即:对象的生成离不开构造函数。第第10章章 构造函数和析构函数构造函数和析构函数 10.2 析构函数

28、析构函数 用用new动动态态分分配配的的对对象象,当当对对象象不不再再使使用用时时即即意意味味着着动动态对象的寿命终结,故应当用态对象的寿命终结,故应当用delete运算符释放它。运算符释放它。实实际际上上,即即使使不不是是动动态态分分配配的的对对象象,当当不不再再使使用用时时,也也意意味味着着其其寿寿命命到到期期,为为此此,C+提提供供了了一一个个用用于于释释放放对对象象所所占资源的成员函数占资源的成员函数析构函数析构函数。第第10章章 构造函数和析构函数构造函数和析构函数 10.2 析构函数析构函数 class A int x,y;public:A(int a=0,int b=0)x=a;

29、y=b;cout“调调 用用 构构 造造 函函 数数”t;void Show()cout“x=”xt“y=”yn;A()cout“调用析构函数调用析构函数”n;;void main(void)A f(5,10);f.Show();析构函数,也是析构函数,也是采用类名代替函数名采用类名代替函数名第第10章章 构造函数和析构函数构造函数和析构函数 10.2 析构函数析构函数 class A int x,y;public:A(int a=0,int b=0)x=a;y=b;cout“调调 用用 构构 造造 函函 数数”t;void Show()cout“x=”xt“y=yt;A()cout“调用析构

30、函数调用析构函数”t;;void main(void)A f(5,10);f.Show();与构造函数相同,函数名前不能用与构造函数相同,函数名前不能用void.与构造函数的不同:左边有与构造函数的不同:左边有“”符号;符号;第第10章章 构造函数和析构函数构造函数和析构函数 10.2 析构函数析构函数 class A int x,y;public:A(int a=0,int b=0)x=a;y=b;cout“调调 用用 构构 造造 函函 数数”t;void Show()cout“x=”xt“y=”yn;A()cout“调用析构函数调用析构函数”n;;void main(void)A f(5,

31、10);f.Show();与构造函数的区别之二与构造函数的区别之二是括号中没有任何参数。是括号中没有任何参数。因此,析构函数是惟一的,不可以重载。因此,析构函数是惟一的,不可以重载。第第10章章 构造函数和析构函数构造函数和析构函数 10.2 析构函数析构函数 class A int x,y;public:A(int a=0,int b=0)x=a;y=b;cout“调调 用用 构构 造造 函函 数数”t;void Show()cout“x=”xt“y=”yn;A()cout“调用析构函数调用析构函数”n;;void main(void)A f(5,10);f.Show();执行过程如下:执行

32、过程如下:定义对象并调用构造函数定义对象并调用构造函数这是形参赋初值的这是形参赋初值的缺省构造函数缺省构造函数所以,对象可以带实参所以,对象可以带实参并将改变构造函数的缺省值并将改变构造函数的缺省值第第10章章 构造函数和析构函数构造函数和析构函数 10.2 析构函数析构函数 class A int x,y;public:A(int a=0,int b=0)x=a;y=b;cout“调调 用用 构构 造造 函函 数数”t;void Show()cout“x=”xt“y=”yn;A()cout“调用析构函数调用析构函数”n;;void main(void)A f(5,10);f.Show();调

33、用对象成员函数调用对象成员函数调用构造函数调用构造函数结果是结果是X=5 y=10主函数结束,主函数结束,对象对象f的生存期也终结,此时的生存期也终结,此时调用析构函数调用析构函数调用析构函数调用析构函数第第10章章 构造函数和析构函数构造函数和析构函数 10.2 析构函数析构函数 class A int x,y;public:A(int a=0,int b=0)x=a;y=b;cout“调调 用用 构构 造造 函函 数数”t;void Show()cout“x=”xt“y=”yn;A()cout“调用析构函数调用析构函数”n;;void main(void)A f(5,10);f.Show(

34、);例题例题10.8(P227)介绍了用介绍了用delete在析构函数中在析构函数中释放指针空间的方法,请务必阅读释放指针空间的方法,请务必阅读有关使用析构函数的一些规则,有关使用析构函数的一些规则,请注意阅读请注意阅读10.2.2、10.2.3、10.2.4节节小小 结结若在类的定义中没有显式地定义构造函数及析构若在类的定义中没有显式地定义构造函数及析构函数,编译器自动产生缺省的构造函数,编译器自动产生缺省的构造/析构函数。析构函数。若在产生对象时不对数据成员初始化,可以不显若在产生对象时不对数据成员初始化,可以不显式地定义构造函数。式地定义构造函数。撤消对象时,若不做任何结束工作,可以不显

35、式撤消对象时,若不做任何结束工作,可以不显式地定义析构函数。地定义析构函数。若对象中有若对象中有new运算符分配的动态空间,必须定运算符分配的动态空间,必须定义析构函数由义析构函数由delete来释放该数据占用空间。来释放该数据占用空间。函数体为空第第10章章 构造函数和析构函数构造函数和析构函数 class A int x,y;public:A(int a,int b)x=a;y=b;cout“x=”xt“y=”y“调用构造函数调用构造函数”n;A()cout“调用析构函数调用析构函数”n;;void main(void)A f(5,6);f=A(7,8);本例中公有成员本例中公有成员包含一

36、个构造函数和一个析构函数包含一个构造函数和一个析构函数第第10章章 构造函数和析构函数构造函数和析构函数 class A int x,y;public:A(int a,int b)x=a;y=b;cout“x=”xt“y=”y“调用构造函数调用构造函数”n;A()cout“调用析构函数调用析构函数”n;;void main(void)A f(5,6);f=A(7,8);定义对象并调用构造函数定义对象并调用构造函数产生的结果是产生的结果是调用构造函数调用构造函数 X=5 y=6第第10章章 构造函数和析构函数构造函数和析构函数 class A int x,y;public:A(int a,int

37、 b)x=a;y=b;cout“x=”xt“y=”y“调用构造函数调用构造函数”n;A()cout“调用析构函数调用析构函数”n;;void main(void)A f(5,6);f=A(7,8);这是个什么语句?这是个什么语句?如何操作呢?如何操作呢?调用构造函数调用构造函数 X=5 y=6第第10章章 构造函数和析构函数构造函数和析构函数 class A int x,y;public:A(int a,int b)x=a;y=b;cout“x=”xt“y=”y“调用构造函数调用构造函数”n;A()cout“调用析构函数调用析构函数”n;;void main(void)A f(5,6);f=A

38、(7,8);调用构造函数调用构造函数 X=5 y=6=右边的含义是:右边的含义是:产生一个产生一个临时对象临时对象并调用构造函数并调用构造函数该该临时对象临时对象中的参数中的参数7,8使构造函数中的数据初始化使构造函数中的数据初始化调用构造函数调用构造函数 X=7 y=8执行结果是执行结果是第第10章章 构造函数和析构函数构造函数和析构函数 class A int x,y;public:A(int a,int b)x=a;y=b;cout“x=”xt“y=”y“调用构造函数调用构造函数”n;A()cout“调用析构函数调用析构函数”n;;void main(void)A f(5,6);f=A(

39、7,8);调用构造函数调用构造函数 X=5 y=6紧接着将紧接着将临时对象临时对象赋给对象赋给对象f,然后然后C+立即撤消这个立即撤消这个临时对象临时对象。这意味着这意味着临时对象临时对象寿命结束,寿命结束,因此需要调用析构函数来释放,结果是因此需要调用析构函数来释放,结果是调用构造函数调用构造函数 X=7 y=8调用析构函数调用析构函数第第10章章 构造函数和析构函数构造函数和析构函数 class A int x,y;public:A(int a,int b)x=a;y=b;cout“x=”xt“y=”y“调用构造函数调用构造函数”n;A()cout“调用析构函数调用析构函数”n;;void

40、 main(void)A f(5,6);f=A(7,8);调用构造函数调用构造函数 X=5 y=6调用构造函数调用构造函数 X=7 y=8调用析构函数调用析构函数调用析构函数调用析构函数所有语句执行完后,所有语句执行完后,对象对象f的寿命结束,因此的寿命结束,因此它也要调用析构函数来释放。结果是它也要调用析构函数来释放。结果是第第10章章 构造函数和析构函数构造函数和析构函数 class A int x,y;public:A(int a,int b)x=a;y=b;cout“调用构造函数调用构造函数”“x=”xt“y=”yn;A()cout“调用析构函数调用析构函数”n;;void main(

41、void)A f(5,6);f=A(7,8);调用构造函数调用构造函数 X=5 y=6从本例中可知调用析构函数的先后顺序和规律从本例中可知调用析构函数的先后顺序和规律调用构造函数调用构造函数 X=7 y=8调用析构函数调用析构函数调用析构函数调用析构函数该语句右边是利用构造函数该语句右边是利用构造函数进行类型转换。本例则是通过转换进行类型转换。本例则是通过转换产生一个类产生一个类A类型的类型的临时对象临时对象这个过程称为这个过程称为 10.3.1 用构造函数实现类型转换用构造函数实现类型转换和拷贝和拷贝第第10章章 构造函数和析构函数构造函数和析构函数 10.3.1 用构造函数实现类型转换和拷

42、贝用构造函数实现类型转换和拷贝 class A int x,y;public:A(int a,int b)x=a;y=b;cout“x=”xt“y=”y“调用构造函数调用构造函数”n;A()cout“调用析构函数调用析构函数”n;;void main(void)A f(5,6);f=A(7,8);那么,主函数中的语句可以改为那么,主函数中的语句可以改为);A f(5);f=7;此时右边常数此时右边常数7的作用与的作用与A(7)完全相同,完全相同,系统此时是采用系统此时是采用默认方式默认方式进行类型转换,进行类型转换,是是隐式类型转换隐式类型转换。而。而A(7)则称为则称为强制转换强制转换,显式

43、类型转换显式类型转换。详细描述请见例题详细描述请见例题10.11(P230)如果构造函数如果构造函数只有一个形参只有一个形参,即,即 当构造函数带多个参当构造函数带多个参数时,必须使用强制数时,必须使用强制类型转换。类型转换。第第10章章 构造函数和析构函数构造函数和析构函数 10.3.1 用构造函数实现类型转换和拷贝用构造函数实现类型转换和拷贝 class A int x,y;public:A(int a,int b)x=a;y=b;cout“调用构造函数调用构造函数”n;A(A&a)x=a.x;y=a.y;cout“调用拷贝函数调用拷贝函数”n;void Show()cout“x=”xt“

44、y=”yn;;如果构造函数的形参是如果构造函数的形参是本本类类类型的引用时类型的引用时void main(void)A f1(5,6);A f2(f1);f1.Show();f2.Show();那么,调用这种函数的实参,那么,调用这种函数的实参,必须是已经创建的同类型的对象必须是已经创建的同类型的对象例如,对象例如,对象f2调用构造函数调用构造函数 A(A&a),它的实参在本例中就必须是对象它的实参在本例中就必须是对象f1第第10章章 构造函数和析构函数构造函数和析构函数 10.3.1 用构造函数实现类型转换和拷贝用构造函数实现类型转换和拷贝 class A int x,y;public:A(

45、int a,int b)x=a;y=b;cout“调用构造函数调用构造函数”n;A(A&a)x=a.x;y=a.y;cout“调用拷贝函数调用拷贝函数”n;void Show()cout“x=”xt“y=”yn;;实际上,这是把对象实际上,这是把对象f1及其数据拷贝到及其数据拷贝到f2void main(void)A f1(5,6);A f2(f1);f1.Show();f2.Show();这里的这里的a.x、a.y中的中的a就相当于就相当于f1第第10章章 构造函数和析构函数构造函数和析构函数 10.3.1 用构造函数实现类型转换和拷贝用构造函数实现类型转换和拷贝 class A int x

46、,y;public:A(int a,int b)x=a;y=b;cout“调用构造函数调用构造函数”n;A(A&a)x=a.x;y=a.y;cout“调用拷贝函数调用拷贝函数”n;void Show()cout“x=”xt“y=”yn;;void main(void)A f1(5,6);A f2(f1);f1.Show();f2.Show();调用构造函数调用构造函数调用拷贝函数调用拷贝函数X=5 y=6X=5 y=6产生的产生的输出输出是是第第10章章 构造函数和析构函数构造函数和析构函数 10.3.1 用构造函数实现类型转换和拷贝用构造函数实现类型转换和拷贝 class A int x,y

47、;public:A(int a,int b)x=a;y=b;cout“调用构造函数调用构造函数”n;A(A&a)x=a.x;y=a.y;cout“调用拷贝函数调用拷贝函数”n;void Show()cout“x=”xt“y=”yn;;void main(void)A f1(5,6);A f2(f1);f1.Show();f2.Show();如果有以下语句:如果有以下语句:A f3=f1;f3.Show();这也是调用仅有一个形参的这也是调用仅有一个形参的构造函数,系统会把它解释为构造函数,系统会把它解释为A f3(f1);而不是看作赋值语句而不是看作赋值语句第第10章章 构造函数和析构函数构造

48、函数和析构函数 10.3.2 实现拷贝功能的实现拷贝功能的构造函数构造函数 一般格式一般格式 ClassName:ClassName(ClassName&c);构造函数的参数是构造函数的参数是ClassName类型的引用;类型的引用;必须用一个已产生的同类型对象作为实参必须用一个已产生的同类型对象作为实参;编译器会为每个类产生一个隐含的拷贝构造函数编译器会为每个类产生一个隐含的拷贝构造函数(浅拷贝函数浅拷贝函数),依次完成对应数据成员的拷贝。,依次完成对应数据成员的拷贝。在以下两种情况下需要显在以下两种情况下需要显式的声明拷贝构造函数:式的声明拷贝构造函数:1.仅拷贝同类型对象的部分成员数据;

49、仅拷贝同类型对象的部分成员数据;2.类中的成员数据中使用类中的成员数据中使用new运算符动态地申请存储空间进行运算符动态地申请存储空间进行赋值时赋值时(深拷贝函数深拷贝函数)。参见教材参见教材 P234例例10.15第第10章章 构造函数和析构函数构造函数和析构函数 10.3.2 实现拷贝功能的实现拷贝功能的构造函数构造函数深拷贝,浅拷贝:当出现类的等号赋值时,会调用拷贝函数。深拷贝,浅拷贝:当出现类的等号赋值时,会调用拷贝函数。在未定义显示拷贝构造函数的情况下,系统会调用默认的拷贝函在未定义显示拷贝构造函数的情况下,系统会调用默认的拷贝函数数即浅拷贝,它能够完成成员的一一复制。即浅拷贝,它能

50、够完成成员的一一复制。当数据成员中没当数据成员中没有指针时,浅拷贝是可行的。有指针时,浅拷贝是可行的。但当数据成员中有指针时,如果采用简单的浅拷贝,则两类中的但当数据成员中有指针时,如果采用简单的浅拷贝,则两类中的两个指针将指向同一个地址,当对象快结束时,会调用两次析构两个指针将指向同一个地址,当对象快结束时,会调用两次析构函数,而导致指针悬挂现象。函数,而导致指针悬挂现象。深拷贝与浅拷贝的区别就在于深拷贝会在堆内存中另外申请空间深拷贝与浅拷贝的区别就在于深拷贝会在堆内存中另外申请空间来储存数据,从而也就解决了指针悬挂的问题。来储存数据,从而也就解决了指针悬挂的问题。简言之,当数据成员中有指针

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

当前位置:首页 > 生活休闲 > 生活常识

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

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