一、什么是析构函数?
析构函数也是一种特殊的成员函数。它执行与构造函数相反的操作,通常用于执行一些清理任务,如释放分配给对象的内存空间等。
二、析构函数的特点是什么?
1、析构函数名与类名相同,但它前面必须加一个波浪号(~)。
2、析构函数不返回任何值。在定义析构函数时,是不能说明它的类型的,甚至说明为void类型也不行。
3、析构函数没有参数,因此它不能被重载。一个类可以有多个构造函数,但是只能有一个析构函数。
4、撤销对象时,编译系统会自动地调用析构函数。
三、例子:既含有构造函数,又含有析构函数。
#include<iostream>
#include<cmath>
using namespace std;
class Complex{
public:
Complex(double r=0.0,double i=0.0); //声明构造函数
~Complex();
double abscomplex();
private:
double real;
double imag;
};
Complex::Complex(double r,double i){
real=r;
imag=i;
cout<<"Constructor called."<<endl;
}
Complex::~Complex(){
cout<<"Destructor called."<<endl;
}
double Complex::abscomplex(){
double t;
t=real*real+imag*imag;
sqrt(t);
}
int main(){
Complex A(1.1,2.2);
cout<<"复数的绝对值是:"<<A.abscomplex()<<endl;
return 0;
}
在执行主函数时先建立对象A,在建立对象A时调用构造函数,对对象A中的数据成员赋初值,然后调用A的函数abscomplex,计算并输出对象A的复数的绝对值。在执行return语句之后,主函数中的语句已执行完毕,对象A的声明周期结束,在撤销对象A时要调用析构函数,释放分配给对象A的存储空间,并显示信息“Destructor called.”。
执行结果如下:
说明:
1、每个类必须有一个析构函数。若没有显式地为一个类定义析构函数,则编译系统会自动地生成一个默认析构函数:
Complex::~Complex(){}
类似于系统自动地生成的默认构造函数,这个自动生成的默认析构函数也是空的,但是它能够完成释放对象所占存储空间的任务。
2、对于大多数类而言,这个默认析构函数就能满足要求。但是,如果在一个对象需要完成另外一些处理工作的话,则应该显示地定义析构函数。例如:
class String_data{
public:
String_data(char *s){ //构造函数
str=new char[strlen(s)+1]; //用运算符new为字符串str动态地分配了一个存储空间
strcpy(str,s);
}
~String_data(){
delete str;
}
void get_info(char *);
void sent_info(char *);
private:
char *str;
};
这是构造函数和析构函数的常见用法,即在构造函数中用运算符new 为字符串分配空间,最后再析构函数中用运算符delete释放已分配的存储空间。
3、析构函数被调用的情况:
①主函数结束(或调用exit函数)时,对象被撤销,系统会自动调用析构函数。
②如果一个对象被定义在一个函数体内,则当这个函数体调用结束时,该对象将释放,析构函数被自动调用。
③若一个对象是使用new运算符动态创建的,在使用delete运算符释放它时,delete会自动调用析构函数。