您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > c++中构造函数和析构函数.
VisualC++程序设计第10章构造函数和析构函数10.1构造函数10.2析构函数10.3实现类型转换和拷贝的构造函数10.4构造函数和对象成员第10章构造函数和析构函数给对象的数据成员赋值有二类(四种)方法:1.定义时赋值(初始化)(1)用数据列表初始化(数据成员为公有访问权限);(2)用构造函数初始化。2.定义后赋值(1)用成员函数赋值----回顾第9章示例3;(2)用同类型的对象赋值。如:classA{public:inta,b;voidset(intx,inty){a=x;b=y;}};voidmain(){Aa1={5,10},a2,a3;a2.set(15,20);a3=a1;}10.1构造函数10.1.1构造函数的概念1.构造函数是实现数据成员初始化的特殊的成员函数;2.构造函数与类同名,没有类型,也不返回值;3.创建对象时,构造函数被自动调用。每创建一个对象都必须调用一次构造函数,每调用一次构造函数必定创建一个对象。10.1.2构造函数的种类1.普通构造函数:普通参数;2.拷贝构造函数:参数为对象的引用。一个类至少有上述两个构造函数,可以有更多的构造函数(构造函数允许重载),以实现不同形式对象的创建。10.1构造函数10.1.3构造函数的定义1.类中定义格式类名(形参列表){...}//函数体,对数据成员赋值2.类中说明,类外定义(1)类中说明类名(形参列表);(2)类外定义类名::类名(形参列表){...}//函数体10.1构造函数例10-1定义表示平面点的类Point及其构造函数。classPoint{floatx,y;public:Point(floata,floatb);Point(floata){x=y=a;}voidprint(){cout‘(‘x‘,’y“)\n”;}};Point::Point(floata,floatb){x=a;y=b;}10.1构造函数10.1.4构造函数产生对象建立对象时,必须提供与构造函数形参一致的实参,其基本格式只有如下两种形式:类名对象名(实参);类名对象名;例10-2用例10-1定义的类定义对象,并初始化。classPoint{floatx,y;public:Point(floata,floatb);Point(floata){x=y=a;}voidprint(){cout‘(‘x‘,’y“)\n”;}};Point::Point(floata,floatb){x=a;y=b;}voidmain(){Pointp1(5),p2(10,15);p1.print();p2.print();}10.1构造函数主函数中,能否添加下列语句:Pointp3;10.1.5缺省的构造函数1.缺省构造函数的种类(1)系统自动产生的构造函数,如下所示:类名(){}(2)用户定义的没有参数的构造函数;(3)用户定义的所有参数都有缺省值的构造函数。2.用缺省构造函数创建对象的格式:类名对象名;3.使用时的注意(1)只有在用户没有定义构造函数时,系统才自动产生构造函数;(2)类中可能没有缺省的构造函数;(3)一个类最多只能有一个缺省的构造函数。10.1构造函数例10-3缺省构造函数的使用。classPoint{floatx,y;public:Point(){x=0;y=0;}Point(floata,floatb){x=a;y=b;}//Avoidprint(){cout‘(‘x‘,’y“)\n”;}};voidmain(){Pointp1,p2(1,2);p1.print();p2.print();}10.1构造函数主函数能否增加:Pointp3();p3.print();能否对A行作如下修改?=0=010.1.6构造函数和new运算符1.用new运行符产生动态对象(1)产生单个对象(可以初始化);(2)产生数组对象(不能初始化)。如:classC{floatr,i;public:C(floatr1,floati1){r=r1;i=i1;cout“构造\n”;}C(){r=i=0;cout“缺省构造\n”;}};voidmain(){C*p1=newC,*p2=newC(2,-3),*p3=newC[5];}10.1构造函数2.用new为指针成员分配动态空间当类的数据成员为指针时,在构造函数中应:·先用new运算符为指针动态分配空间;·然后再对指针所指空间赋值。如:classArray{int*p;...};//p表示10个元素的一维数组则如下的构造函数都是错误的:Array(int*t){p=t;}Array(int*t){*p=*t;}Array(int*t){for(inti=0;i10;i++)p[i]=t[i];}Array(int*t){p=newint[10];p=t;}//*p=*t;正确的应为:Array(int*t){p=newint[10];//分配动态空间for(inti=0;i10;i++)p[i]=t[i];//对动态空间赋值}10.1构造函数1.析构函数的概念用于撤消对象的成员函数。2.定义格式(1)类中定义~类名(){...}//函数体(2)类中说明,类外定义①类中说明~类名();//类中说明②类外定义类名::~类名()//类外定义{...}//函数体10.2析构函数3.使用时注意:(1)析构函数的名称由运算符‘~’与类名组成;(2)析构函数无函数类型,无参数,且不返回值;(3)析构函数不可以重载,每个类只有一个析构函数;(4)类中通常不需要定义析构函数,而由系统自动产生一个如下的缺省析构函数:类名::~类名(){}(5)当类中用new运算符分配了动态空间时,必须定义析构函数,并在函数体中用delete运算符释放动态空间。4.构造函数与析构函数的调用过程在创建对象时,调用构造函数;在撤消对象时,调用析构函数;所以它们的调用过程(顺序)通常是相反的。10.2析构函数10.3.1实现类型转换的构造函数当一个对象被赋值为一个数字,如果这个数字可以放入某个构造函数实现对这个构造函数的调用时,则该赋值语句成立。其实质是以所给的数据为参数调用普通的构造函数初始化对象,此时的构造函数称为类型转换的构造函数。例10-4用类型转换的构造函数初始化对象。classEx{intx,y;public:Ex(inta,intb=10){x=a;y=b;cout“x=”x“,y=”y“\n”;}~Ex(){coutx“,释放对象。\n”;}};voidmain(){Exe1(5);Exe2=15;e1=20;cout“End.\n”;}10.3实现类型转换和拷贝的构造函数其中:Exe2=15;等同于Exe2(15);e1=20;等同于e1=Ex(20);x=5,y=10x=15,y=10x=20,y=1020,释放对象。End.15,释放对象。20,释放对象。10.3.2完成拷贝功能的构造函数拷贝功能的构造函数实现:用一个已建立的对象初始化同类型的对象,其调用格式为:类名新对象名(已建立对象名);或类名新对象名=已建立对象名;例10-5用拷贝构造函数初始化对象。classEx{intx,y;public:Ex(inta,intb){x=a;y=b;cout“x=”x“,y=”y“,普通构造。\n”;}Ex(Ex&t)//拷贝功能的构造函数{x=t.x;y=t.y;cout“x=”x“,y=”y“,拷贝构造。\n”;}};voidmain(){Exe1(5,10);Exe2(e1);Exe3=e2;}10.3实现类型转换和拷贝的构造函数x=5,10,普通构造x=5,10,拷贝构造x=5,10,拷贝构造与普通构造函数相似,若用户不定义拷贝功能构造函数,系统自动产生一个缺省的拷贝功能构造函数,它把已建立对象各数据成员的值依次赋给新对象。其定义如下:类名::类名(类名&对象名){*this=对象名;}用户通常可以直接使用缺省的拷贝功能构造函数,但在以下情况下必须重新定义:(1)新建对象与已建立对象的数据有差异;如:Ex2e2(e1);(2)数据成员中有指针,并使用了动态内存。类的构造函数有两类、多种形式,使用时应加以区分。10.3实现类型转换和拷贝的构造函数例10-6用普通构造函数和拷贝构造函数创建对象。classA{public:A(intx=1){coutx“\t”;}A(A&t){cout“拷贝\t”;}};voidmain(){Aa1,a2(2),a3=3;cout‘\n’;Aa4=A(4),a5=a1,a6(a1);cout‘\n’;a1=5;a2=a1;a3=A(0);cout‘\n’;}10.3实现类型转换和拷贝的构造函数运行结果:1234拷贝拷贝拷贝50程序中共创建了几个对象?1.对象成员的概念类的数据成员为其他已定义类的对象,该成员称为对象成员。2.初始化对象成员的方法在构造函数中以对象名调用对象所属类的构造函数完成,其基本格式为:类名::类名(形参表):对象名(实参表){……}//初始化普通成员3.当前对象在初始化(构造函数调用)时的顺序(1)先完成对象成员的初始化,有多个对象成员时,先说明的先初始化;(2)再完成普通成员的初始化。即先调用对象成员所属类的构造函数,再执行自身类的函数体。4.对象的撤消(析构函数调用)顺序:与建立顺序相反。10.4构造函数和对象成员例10-7含对象成员类的构造函数。classA{inta;public:A(intx=0){a=x;cout“A()\n”;}~A(){couta“~A()\n”;}};classB{intb;public:B(intx=0){b=x;cout“B()\n”;}~B(){coutb“~B()\n”;}};classC{intc;Bb1;Aa1;Bb2;public:C(intx,inty,intz):a1(x),b1(y),b2(z){c=x+y+z;cout“C()\n”;}~C(){coutc“~A()\n”;}};voidmain(){Cc1(1,2,3);}10.4构造函数和对象成员对象说明顺序决定构造函数调用顺序对象调用构造函数语句决定对象成员的值一、选择题1、以下有关析构函数的叙述不正确的是。A、析构函数没有任何函数类型B、析构函数的作用是在撤销对象时收回分配的内存空间C、析构函数可以有形参D、一个类只有一个析构函数2、关于类的缺省构造函数,下列说法正确的是。A、类的缺省构造函数没有参数B、类的缺省构造函数是由系统自动产生的空函数C、每个类均可定义缺省的构造函数D、每个类均有且有一个缺省的构造函数3、通常拷贝初始化构造函数的参数是。A、某个对象的名称B、某个对象的成员名C、指向某个对象的指针名D、某个对象的引用名课堂练习4、设有如下类的定义:classEx{int*p;public:~Ex(){deletep;}Ex(intx=0){p=newint(x);}};则下列对象的定义中,不正确的是。A、Exex;B、Exex1(50),ex2=ex1;C、Exex=Ex(50);D.Exex=50;5、下列关于构造函数说法不正确的是。A、构造函数必须与类同名B、构造函数可以省略不写C、构造函数必须有返回值D、在构造函数中可以对类中的成员进行初始化6、已定义类A,该类构造函数的参数都没有缺省值,执行语句:Aa1(2),a2(1,2),*p=newA[3];则自动调用该类的缺省构造函数的次数为。A、1B、3C、2D、5课堂练习7、下列程序中出现编译错误的是。#includeiostream.hclassA{inta,b;public:A(intx,inty){a=x;b=y;}voidprint(){couta’\t’b’\n’;}};voidmain(){At;
本文标题:c++中构造函数和析构函数.
链接地址:https://www.777doc.com/doc-2901577 .html