1C++中,提供了用一个对象值创建并初始化另一个对象的方法,完成该功能的是拷贝构造函数。例如:Tdated1(2002,3,1);Tdated2(d1);用构造函数创建d1的值初始化新创建的对象d2。拷贝构造函数的特点:1、拷贝构造函数名字与类同名,没有返回类型;2、拷贝构造函数只有一个形参数,该参数是该类的对象的引用;拷贝构造函数(CopyConstructor)拷贝构造函数23、拷贝构造函数的格式如下:类名::拷贝构造函数名(类名&引用名){函数体}其中,拷贝构造函数名与该类名相同;例如:下面程序说明了调用拷贝构造函数的过程#includeiostream.hclassTpoint{public:Tpoint(intxp,intyp){x=xp;y=yp;}Tpoint(Tpoint&p);//拷贝构造函数拷贝构造函数3intxcoord(){returnx;}intycoord(){returny;}private:intx,y;};Tpoint::Tpoint(Tpoint&p){x=p.x;y=p.y;cout“Copy_initializationconstructorcalled.\n”;}拷贝构造函数4voidmain(){Tpointp1(5,7);Tpointp2(p1);cout“p2=”p2.xcoord()“,”p2.ycoord()endl;}结果:Copy_initializationconstructorcalled.P2=5,7拷贝构造函数5注意:如果一个类中没有定义拷贝构造函数,则系统自动生成一个缺省拷贝构造函数,其功能是将已知对象的所有数据成员的值拷贝给对应对象的数据成员。•classA{•floatx,y;•public:•A(floata,floatb)•{x=a;y=b;cout调用了构造函数\n;}•voidPrint(){coutx'\t'yendl;}•};拷贝构造函数6•调用了构造函数•1.02.0•1.02.0•1.02.0voidmain(void){Aa1(1.0,2.0);Aa2(a1);Aa3=a1;//可以这样赋值a1.Print();a2.Print();a3.Print();}拷贝构造函数7拷贝构造函数举例classPoint{public:Point(intxx=0,intyy=0){X=xx;Y=yy;}Point(Point&p);intGetX(){returnX;}intGetY(){returnY;}private:intX,Y;};Point::Point(Point&p){X=p.X;Y=p.Y;cout拷贝构造函数被调用endl;}拷贝构造函数8拷贝构造函数调用(1)当用类的一个对象去初始化该类的另一个对象时系统自动调用拷贝构造函数实现拷贝赋值。voidmain(void){PointA(1,2);PointB(A);//拷贝构造函数被调用coutB.GetX()endl;}拷贝构造函数9(2)若函数的形参为类对象,调用函数时,实参赋值给形参,系统自动调用拷贝构造函数。例如:voidfun1(Pointp){coutp.GetX()endl;}voidmain(){PointA(1,2);fun1(A);//调用拷贝构造函数}拷贝构造函数10(3)当函数的返回值是类对象时,系统自动调用拷贝构造函数。例如:Pointfun2(){PointA(1,2);returnA;//调用拷贝构造函数}voidmain(){PointB;B=fun2();}拷贝构造函数11注意:如果程序员没有为类声明拷贝初始化构造函数,则编译器自己生成一个拷贝构造函数。这个构造函数执行的功能是:用作为初始值的对象的每个数据成员的值,初始化将要建立的对象的对应数据成员。拷贝构造函数12构造函数和析构函数举例#includeiostreamusingnamespacestd;classPoint{public:Point(intxx,intyy);~Point();//...其它函数原形private:intX,intY;};Point::Point(intxx,intyy){X=xx;Y=yy;}Point::~Point(){}//...其它函数的实现略构造函数和析构函数13构造函数和析构函数调用举例#includeiostream.husingnamespacestd;classQ{intx,y;public:Q(inta=0,intb=0){cout“调用了构造函数”endl;x=a;y=b;}voidP(void){coutx‘\t’y‘\n’;}~Q(){cout“调用了析构函数!”‘\n’;}voidmain(void){Qq(50,100);q.P();cout“退出主数!”\n”;}输出:调用了构造函数50100退出主函数!调用了析构函数!构造函数和析构函数14类的应用举例一圆型游泳池如图所示,现在需在其周围建一圆型过道,并在其四周围上栅栏。栅栏价格为35元/米,过道造价为20元/平方米。过道宽度为3米,游泳池半径由键盘输入。要求编程计算并输出过道和栅栏的造价。游泳池过道构造函数和析构函数15#includeiostreamusingnamespacestd;constfloatPI=3.14159;constfloatFencePrice=35;constfloatConcretePrice=20;classCircle//声明类Circle及其数据和方法{private:floatradius;public:Circle(floatr);//构造函数floatCircumference();//圆周长floatArea();//圆面积};Circle::Circle(floatr)//构造函数初始化数据成员radius{radius=r;}floatCircle::Circumference()//计算圆的周长{return2*PI*radius;}floatCircle::Area()//计算圆的面积{returnPI*radius*radius;}构造函数和析构函数16voidmain(){floatradius;floatFenceCost,ConcreteCost;coutEntertheradiusofthepool:;//提示用户输入半径cinradius;CirclePool(radius);//声明Circle对象CirclePoolRim(radius+3);FenceCost=PoolRim.Circumference()*FencePrice;//计算栅栏造价并输出coutFencingCostis¥FenceCostendl;ConcreteCost=(PoolRim.Area()-Pool.Area())*ConcretePrice;//计算过道造价并输出coutConcreteCostis¥ConcreteCostendl;}运行结果Entertheradiusofthepool:10FencingCostis¥2858.85ConcreteCostis¥4335.3构造函数和析构函数17#include“tpoint.h”Tpointfun(Tpointq);voidmain(){TpointM(12,20),P(0,0),S(0,0);TpointN(M);P=fun(N);S=M;cout“P=”P.xcoord()“,”P.ycoord()endl;cout“S=”S.xcoord()“,”S.ycoord()endl;}Tpointfun(Tpointq){cout“OK\n”;intx=q.xcoord()+10;inty=q.ycoord()+15;18TpointR(x,y);returnR;}//…tpoint.h#includeiostream.hclassTpoint{public:Tpoint(intxp,intyp){x=xp;y=yp;}Tpoint(Tpoint&p);~Tpoint(){cout“Destructorcalled.\n”;}intxcoord(){returnx;}intycoord(){returny;}private:intx,y;};19Tpoint::Tpoint(Tpoint&p){x=p.x;y=p.y;cout“Copy_initializationconstructorcalled.\n”;}输出结果如下:Copy_initializationconstructorcalled.Copy_initializationconstructorcalled.OKCopy_initializationconstructorcalled.Destructorcalled.Destructorcalled.Destructorcalled.20P=22,35S=12,20Destructorcalled.Destructorcalled.Destructorcalled.Destructorcalled.程序输出结果说明程序中出现了三次调用构造函数:TpointN(M);//M对象创建N对象P=fun(N);//实参N对象被拷贝到形参q对象returnR;//函数返回时,调用拷贝构造函数,用对象R创建//一个临时对象,保存R的数据,在主函数中临//时对象被释放前,将它的内容赋值到对象P中。临时对象P放入取出Rfun()主函数暂存区main()区临时对象起暂存作用的情况如下图所示:21组合的概念类中的成员数据是另一个类的对象。可以在已有的抽象的基础上实现更复杂的抽象。通过对复杂对象进行分解、抽象,使我们能够将一个复杂对象理解为简单对象的组合;分解得到复杂对象的部件对象,这些部件对象比它高层的复杂对象更容易理解和实现,然后由这些部件对象了“装配”复杂对象类的组合22例如:#includeiostream.hclassStudent{public:Student(){cout“Constructingstudent.\n”;semeshours=100;gpa=3.5;}23~Student(){cout“Destructingstudent.\n”;}protected:intsemeshours;floatgpa;};classTeacher{public:Teacher(){cout“Constructingteacher.\n”;}24~Teacher(){cout“Destructingteacher.\n”;}};classTutorpair{public:Tutorpair(){cout“Constructingtutorpair.\n”;nomeetings=0;}~Tutorpair(){cout“Destructingtutorpair.\n”;}25protected:Studentstudent;Teacherteacher;intnomeetings;};voidmain(){Tutorpairtp;cout“Backinmain.\n”;}Constructingstudent.Constructingteacher.Constructingtutorpair.Backinmain.Destructingtutorpair.Destructingteacher.Destructingstudent.运行结果:26举例classPoint{private:floatx,y;//点的坐标public:Point(floath,floatv);//构造函数floatGetX(