您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 补充C++2_构造函数与析构函数B.
构造函数与析构函数本章着重讨论构造函数、析构函数及用构造函数初始化对象。要求理解构造函数的作用,并掌握用构造函数初始化对象的方法。掌握构造函数的类型转换、掌握给对象赋值和使用对象成员的方法。本章的重点是构造函数,难点是构造函数初始化对象。不能直接在定义类时给数据成员初始化类的定义,初始化无效构造函数和析构函数classc{intn=0;intrint=n;//….}可以用初始化列表给没有定义构造函数的类的对象初始化:classInit{public:inti;char*name;floatnum[2];};InitC={34,“program”,{56.89,1.2}};num[0]=56.89num[1]=1.2构造函数----给对象进行初始化的更强和更一般的方法构造函数:(1)与类名同名(2)不能指定返回类型,即使void也不行(3)构造函数可以有多个参数也可以没有参数。(4)当定义一个类的对象或者是用new生成类的对象时,编译器自动执行这个类的构造函数。构造函数几种构造函数1.自动缺省构造函数:当你没有声明构造函数时,C++编译器会自动生成一个不带参数的构造函数,它的用处不大。2.缺省构造函数:这些函数没有参数。一个类只有一个缺省构造函数。3.复制初始化构造函数:利用现存实例的状态来生成实例,一个类只有一个拷贝构造函数。4.定制构造函数:按你所选的方式来初始化类实例。一个类可以有几个用户定制的构造函数。//Test1.h定义构造函数classTest{private:intnum;public:Test();Test(int);};定义构造函数//Test1.cpp#includeiostream.h#include“Test1.h”Test::Test(){cout“Initdefault”endl;num=0;}Test::Test(intn){cout“Init”nendl;num=n;}voidmain(){Testx;Testy(15);Testarray[2]={5,7};}运行结果:InitdefaultInit15Init5Init7构造函数几点注意1.说明一个外部对象时,程序不为外部对象说明构造函数。2.如果是全局对象或静态对象,在main函数之前要调用它们的构造函数。//Test1.h定义构造函数classTest{private:intnum;public:Test();Test(int);};//Test1.cpp#includeiostream.h#include“Test1.h”Test::Test(){cout“Initdefault”endl;num=0;}Test::Test(intn){cout“Init”nendl;num=n;}Testglobal(5);voidmain(){cout“EnterMain”endl;cout“ExitMain”endl;}运行结果:Init5EnterMainExitMain在main执行前调用构造函数构造函数和运算符new运算符new用于建立生存期可控的对象,new返回这个对象的指针。new建立动态对象的语法和建立动态变量相似,不同的是new是和构造函数一同起作用的。voidmain(){Test*ptr1=newTest(5);/*new首先分配内存,再调用构造函数初始化对象,返回这个动态对象的地址。*/deleteptr1;//删除对象并释放内存空间}复制初始化构造函数形如X::X(X&)的构造函数称为复制(拷贝)初始化构造函数,这个函数以它所在类的对象的引用作为参数。它可以访问对象的私有成员。该函数可用于以该类的一个对象初始化该类的另一个对象时。classTest{private:intnum;floatf1;Public:Test(int,float)Test(Test&);};Test::Test(intn,floatf){num=n;f1=f;}Test::Test(Test&t){num=t.num;f1=t.f1;}在一个类中定义的成员函数可以访问任何该类对象的私有成员。析构函数析构函数名与类名相同,但在其函数名前冠以一个浪纹号(~),以区别于构造函数。定义析构函数时不能定义任何返回类型,也不能指定任何参数。一个类只能定义一个析构函数。如Test类的析构函数:~Test()析构函数在对象的生存期结束时被自动调用,回收这个对象占用的内存空间。例:定义析构函数//Test2.hclassTest{private:intnum;floatf1;public:Test();~Test();};//Test2.cpp#includeiostream.h#include“Test2.h”Test::Test(){num=0;f1=0.0;cout“Begin”numendl;}Test::~Test(){cout“Over”endl;}voidmain(){Testx;cout“Exitmain”endl;}Begin0ExitmainOver运行结果:析构函数析构函数在对象生存期结束时被自动调用,对象的生存期在遇到右花括号}时结束。全局对象和静态对象的析构函数在程序运行结束之前调用。Testy;//y为全局对象voidmain(){Testx;cout“Exitmain”endl;}例:程序结束自动调用全局对象的析构函数//Test2.hclassTest{private:intnum;floatf1;public:Test();Test(intn,floatf);~Test();};//Test2.cpp#includeiostream.h#include“Test2.h”Test::Test(){num=n;f1=0.0;}Test::Test(intn,floatf){num=n;f1=f;}Test::~Test(){cout“Over”endl;}Testy;//y为全局对象voidmain(){cout“Exitmain”endl;}ExitmainOver运行结果:析构函数当使用系统函数exit终止一个程序的运行时,也调用全局对象和静态对象的析构函数。#includeiostream.h#include“Test2.h”Testglobal;voidmain(){exit(0);cout“Exitmain”endl;}例:终止程序运行时自动调用全局对象的析构函数//Test2.hclassTest{private:intnum;floatf1;public:Test();~Test();};//Test2.cpp#includeiostream.h#include“Test2.h”Test::Test(){num=0;f1=0.0;}Test::~Test(){cout“Over”endl;}Testy;voidmain(){exit(0);cout“ExitMain”endl;}运行结果:Over在析构函数中不能使用exit(),必要时可用abort()。例:析构函数中不能用exit()//Test2.hclassTest{private:intnum;floatf1;public:Test();~Test();};//Test2.cpp#includeiostream.h#include“Test2.h”Test::Test(){num=0;f1=0.0;}Test::~Test(){exit(0);cout“Over”endl;}voidmain(){Testx;cout“ExitMain”endl;}析构函数中不能使用exit函数对象数组析构对象数组的生命周期结束之后,C++系统为对象数组的每个元素调用一次析构函数。如Test::~Test(){cout“over”endl;}voidmain(){Testarray[2];cout“Exitingmain”endl;}//两次调用~Test()运行结果:Exitingmainoveroverdelete当使用运算符delete删除一个动态对象时,它首先为这个动态对象调用析构函数,然后再释放这个动态对象所占用的内存空间。//Test2.hclassTest{private:intnum;floatf1;public:Test();~Test();};//Test2.cpp#includeiostream.h#include“Test2.h”Test::Test(){num=0;f1=0.0;}Test::~Test(){cout“Over”endl;}voidmain(){Test*ob=newTest();deleteob;cout“ExitMain”endl;}运行结果:Over例:用delete删除动态对象ExitMain删除deleteob;运行结果是什么?例:没有用delete删除动态对象//Test2.hclassTest{private:intnum;floatf1;public:Test();~Test();};//Test2.cpp#includeiostream.h#include“Test2.h”Test::Test(){num=0;f1=0.0;}Test::~Test(){cout“Over”endl;}voidmain(){Test*ob=newTest();//deleteob;cout“ExitMain”endl;}运行结果:ExitMainOverdelete用delete释放动态对象数组时,应用delete[]对象数组名;如:delete[]ptr;使delete知道ptr指向的是动态对象数组,并为动态数组的每个对象调用一次析构函数,最后释放ptr所指向的内存。//Test2.hclassTest{private:intnum;floatf1;public:Test();~Test();};//Test2.cpp#includeiostream.h#include“Test2.h”Test::Test(){num=0;f1=0.0;}Test::~Test(){cout“Over”endl;voidmain(){Test*p=newTest[2];delete[]p;}运行结果:Over例:用delete删除动态对象数组Overdelete[]p知道p指向动态对象数组,delete将为每个对象调用一次析构函数缺省析构函数每个对象都有一个析构函数,如果在定义一个类时没有定义一个析构函数,C++编译器会自动建立一个缺省析构函数。该函数的函数体是空的,即它除释放构造函数分配的内存空间外,什么也不做。Test::~Test(){}全局对象或静态对象的构造函数和析构函数1.构造函数:全局对象和静态对象的构造函数在main函数之前就调用它们的构造函数,对对象进行初始化。2.析构函数:全局对象和静态对象的析构函数在程序运行结束之前调用。当系统函数exit终止一个程序的运行时,也调用全局对象和静态对象的析构函数。为防止程序的无限递归,在析构函数中不能使用exit()函数,必要时可使用abort()函数退出。构造函数和析构函数的调用时间:对象类型构造函数调用析构函数调用全局对象程序运行程序结束局部对象对象定义处离开程序块静态局部对象对象定义处程序结束New动态创建的对象创建对象处Delete显式撤消独立练习:(8~10分钟)(只作前两道题目:分析程序题1和3)P58:分析程序题1:写出程序运行结果。P59:分析程序题3:写出程序运行结果。回答:P61:编程题2怎样显式调用构造函数?P61:编程题3怎样显式调用析构函数?构造函数类型转换一个对象可以作为操作数用在表达式中,在对表达式求值时,可能需要
本文标题:补充C++2_构造函数与析构函数B.
链接地址:https://www.777doc.com/doc-2031319 .html