七、析构函数 destructors
1)基本概念
- 名字与类名相同,在前面加‘~’ , 没有参数和返回值,一 个类最多只能有一个析构函数。
- 析构函数对象消亡时即自动被调用。可以定义析构函数来在对象消亡前做善后工作,比如释放分配的空间等。
- 如果定义类时没写析构函数,则编译器生成缺省析构函数。 缺省析构函数什么也不做。
- 如果定义了析构函数,则编译器不生成缺省析构函数。
实例:
class String{ private : char * p; public: String () { p = new char[10]; } ~ String () ; }; String ::~ String() { delete [] p; }
2)构造函数和数组
对象数组生命期结束时,对象数组的每个元素的析构函数都会被调用。
class Ctest { public: ~Ctest() { cout<< "destructor called" << endl; } }; int main () { Ctest array[2]; cout << "End Main" << endl; return 0; }
输出:
End Main
destructor called
destructor called
3)析构函数和运算符 delete
- delete 运算导致析构函数调用。
Ctest * pTest; pTest = new Ctest; //构造函数调用 delete pTest; //析构函数调用 pTest = new Ctest[3]; //构造函数调用3次 delete [] pTest; //析构函数调用3次
若new一个对象数组,那么用delete释放时应该写 []。否则只delete一个对象(调用一次析构函数)
- 析构函数在对象作为函数返回值返回后被调用
class CMyclass { public: ~CMyclass() { cout << "destructor" << endl; } }; CMyclass obj; CMyclass fun(CMyclass sobj ) { //参数对象消亡也会导致析 //构函数被调用 return sobj; //函数调用返回时生成临时对象返回 } int main(){ obj = fun(obj); //函数调用的返回值(临时对象)被 return 0; //用过后,该临时对象析构函数被调用 }
输出:
destructor
destructor
destructor
4)构造函数和析构函数 什么时候被调用?
class Demo { int id; public: Demo(int i) { id = i; cout << "id=" << id << " constructed" << endl; } ~Demo() { cout << "id=" << id << " destructed" << endl; } }; Demo d1(1); void Func() { static Demo d2(2); Demo d3(3); cout << "func" << endl; } int main () { Demo d4(4); d4 = 6; cout << "main" << endl; { Demo d5(5); } Func(); cout << "main ends" << endl; return 0; }
输出结果:
id=1 constructed
id=4 constructed
id=6 constructed
id=6 destructed
main
id=5 constructed
id=5 destructed
id=2 constructed
id=3 constructed
func
id=3 destructed
main ends
id=6 destructed
id=2 destructed
id=1 destructed
注意:new 出来的,必须delete才会消亡,否者整个程序结束都不会消亡。