[C++]8.3.4 析构函数的定义与使用

析构函数的作用与构造函数正好相反,是在对象的生命期结束时,释放系统对象所分配的空间前,做一些善后工作。

析构函数也是类的成员函数,定义析构函数的格式为:

ClassName::~ClassName( )
{
… //函数体
}

例:为类定义析构函数。

#include<iostream.h>
class  C
{	int i;
public:
	C (){  i=0; cout<<"Constructor\n";}
	void disp() {    cout<<"i="<<i<<‘\n’;}
	~C (){    cout<<"Destructor"<<endl; }
};
void main()
{	C a; 
	a.disp();
}//释放对象,调用析构函数
 输出结果:
 Constructor
 i=0
 Destructor

关于析构函数的几点说明:
 1、析构函数是一个特殊的函数,它的名字与类名相同,并在前面加==“~”字符==,用来与构造函数加以区别。
 析构函数不指定数据类型,并且也没有参数
 
 2、一个类中可能定义一个析构函数。
 
 3、析构函数是成员函数,函数体可写在 类体内,也可写在 类体外
 
4、同 构造函数 一样,如果没有为类定义析构函数,系统会自动为类添加一个默认的析构函数,函数体为空。

5、析构函数可以被显式调用(不推荐),也可以系统调用。在下面两种情况下,析构函数会被自动调用

  • 如果一个对象是局部的,它具有块作用域,当对象所在的块结束时,该对象的析构函数被自动调用。
  • 全局对象静态对象程序运行结束时,该对象的析构函数被自动调用。

6、当一个对象是使用new运算符动态创建的,在使用delete运算符释放它时,delete将会 自动调用 析构函数。 如果不使用delete运算符释放,即使到了程序结束,也不会自动调用析构函数释放它。

例:复杂对象的构造函数和析构函数调用
class Sample
{ int x;
public:
Sample(int a=0) //构造函数

	{    x=a;
	     cout<<"Constructore, x="<<x<<endl;
	}
	~Sample()			//析构函数
	{   cout<<"Destructor, x="<<x<<endl;}
	void disp()			//输出函数
	{   cout<<"x="<<x<<endl;}
};
void fun(int i)
{	static Sample s2(i);   //静态对象s2
      Sample s3;  //局部对象s3
	s2.disp();
}     //s3生命期结束
Sample s1;	//全局对象s1,其x=0
void main()
{	Sample s4(50), *ptr=new Sample(100);
	fun(10);
	fun(20);
	delete ptr;	//释放动态对象
}	//s1、s2、s4生命期结束

定义全局对象s1: Constructore, x=0
定义局部对象s4: Constructore, x=50
定义动态对象ptr: Constructore, x=100
定义静态对象s2: Constructore, x=10
定义局部对象s3: Constructore, x=0
输出对象s2: x=10
释放局部对象s3: Destructor, x=0
定义局部对象s3: Constructore, x=0
输出对象s2: x=10
释放局部对象s3: Destructor, x=0
释放动态对象ptr: Destructor, x=100
释放局部对象s4: Destructor, x=50
释放静态对象s2: Destructor, x=10
释放全局对象s1: Destructor, x=0

(先定义,先释放;后定义,后释放)

注意!
在程序的执行过程中,对象如果用 new运算符 开辟了空间,则在类中应该 自己定义一个析构函数,并在析构函数中 使用delete 删除由new分配的内存空间。
(下面是例子)

class Str{
     char  *Sp;  int Length;
public:
     Str(char *string)
     {   if(string){	Length=strlen(string);
	     Sp=new char[Length+1];//申请动态内存,用成员数据指针指向

	     strcpy(Sp,string);//初始化动态空间

          }
	 else  Sp=0;
     }
     void Show(void){	cout<<Sp<<endl;}
     ~Str(){  if(Sp)  delete [ ]Sp;  }//释放对象时收回用new开辟的空间

};
void main(void)
{    Str s1("Study C++");
      s1.Show();
}

  • 使用构造函数可以实现类型转换。

例:使用构造函数实现强制类型转换。

#include<iostream.h>
class Point  {   int x,y;
public:
    ~Point()  {  cout<<"调用了析构函数!\n";}
    Point(int a, int b)
    {  x=a; y=b;
	cout<<"x="<<x<<",y="<<y<<
                                  "\t调用了构造函数!\n";  }
};
void main()
{	Point p1(5,10);
	p1=Point(50,100);//创建临时对象、赋值,再释放

}

程序输出为:
x=5,y=10 调用了构造函数!
x=50,y=100 调用了构造函数!
调用了析构函数!
调用了析构函数!

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页

打赏作者

Tranquility_5

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值