析构函数的简单认识

什么析构函数?
析构函数和构造函数一样,析构函数也是类的特殊成员函数,不用调用便自动执行,而且析构函数的名字也是与类的名字有关。
·
在前面我们可以知道,c++程序设计的一个原则是,由系统自动分批的内存空间由系统自动释放,而手工分配的内存空间必须手动释放,否则可能会造成内存的泄露。
·
我们先看如下问题实例:

#include<iostream>
#include<cstring>
using namespace std;
class my
{
	int n;
	char* p;
public:
	my(int na, char* pa)
	{
		n = na;
		p = new char[20];
		strcpy(p, pa);
	}
	void print()
	{
		cout << "n:" << n << " " << "p:" << p << endl;
	}
};
int main()
{
	my a(1, "mary");
	a.print();
	return 0;
}

在这里插入图片描述

上面程序是可以正常运行的,但是的确的存在问题。
当我们定义my的类对象a时,此对象如图所示
在这里插入图片描述
在构造函数中为pname的指针分配指向的内存空间,然后赋值“mary”字符串,但是程序执行完,pname所指向的空间没有释放。
解决问题的方法是使用析构函数,就是将pname所指向的空间的代码放在析构函数中,my类所示的析构函数如下图所示:

~my
{
	delete pname;
}

从这个例子中我们可以看出,一个类可以在构造函数中里分配资源,这些资源需要在对象不复存在以前被释放。析构函数就是完成这种释放资源的清理工作的。
如同默认构造函数一样,如果一个类没有定义析构函数,编译器会自动生成一个默认的析构函数。
·
·
析构函数的性质
·析构函数在类的对象销毁时自动执行
·一个类只能有一个析构函数,而且析构函数没有参数
·析构函数的名字时“~”加上类的名字(中间没有空格)
·与构造函数一样,析构函数没有任何类型,既不属于返回值函数也不属于void函数,他们不能像其他函数那样被调用
·
·
析构函数的调用
1·用类直接建立对象

#include<iostream>
using namespace std;
class reca
{
private:
	int x1, x2, y1, y2;
public:
	reca(int a1, int b1, int a2, int b2)
	{
		cout << "调用到参数构造函数" << endl;
		x1 = a1;
		x2 = a2;
		y1 = b1;
		y2 = b2;
	}
	reca()
	{
		cout << "调用无参构造函数" << endl;
		x1 = 0;
		y1 = 0;
		x2 = 0;
		y2 = 0;
	}
	int area()
	{
		return (x2 - x1) * (y2 - y1);
	}
	~reca()
	{
		cout << "调用了析构函数" << endl;
	}

};
int main()
{
	reca r1(1, 3, 8, 12);
	cout << "矩形r1的面积:" << r1.area()<< endl;
	reca r2;
	cout << "矩形r2的面积:" << r2.area()<< endl;
	return 0;
}

在这里插入图片描述
在上述程序中,对象r1,r2在主程序中main()结束遇到后括号时,会自动那调用析构函数,因此输出的结果中会有两个“调用了析构函数”.

`

`

`
2用new动态创建对象
对于用new运算动态创建的对象,在产生对象时调用构造函数,只有用delete释放对象时,才会调用析构函数。若不使用delete运算符来撤销动态生成的对象,程序结束时对象仍存在,并占用相应的存储空间,即系统不能自动撤销动态创建的对象。
认真分析如下实例:

#include<iostream>
using namespace std;
class tpoint
{
	int x, y;
public:
	tpoint(int x1, int y1)
	{
		x = x1;
		y = y1;
	}
	~tpoint()
	{
		cout << "调用析构函数" << endl;
	}
	void dispoint()
	{
		cout << "(" << x << "," << y << ")" << endl;
	}
};
int main()
{
	tpoint a(12, 6);
	tpoint* p;
	p = new tpoint(4, 13);
	cout << "First point =>";
	a.dispoint();
	cout << "Second point =>";
	p->dispoint();
	delete p;
	return 0;
}

在这里插入图片描述
从程序的执行结果可以看出,对于类对象,系统会自动释放它并且自动调用析构函数,程序中的对象
a就是这样的。
对于用new运算符创建的对象,必须在delete运算符释放时才能调用析构函数,程序中的对象指针p使用delete释放,所以调用析构函数。
·
·
·如果我们不使用 new,delete,析构函数的话,应该这样做:

int main()
{
	tpoint a(12, 6);
	tpoint* p;
	tpoint q(4,13);
	p = &q;
	cout << "First point =>";
	a.dispoint();
	cout << "Second point =>";
	p->dispoint();
	return 0;
}

因为这个tpoint只是一个类的名字,不是变量,不可以分配内存,没有地址。所以我们还应该在声明一个变量,如上图所示。
·
·
·
认真分析经典例题:

#include<iostream>
using namespace std;
class line
{
public:
	void setlength(double len);
	double getlength(void);
	line();
	~line();
private:
	double length;
};
line::line(void)
{
	cout << "object is being created" << endl;
}
line::~line(void)
{
	cout << "deleted" << endl;
}
void line::setlength(double len)
{
	length = len;
}
double line::getlength(void)
{
	return length;
}
int main()
{
	line lin;
	lin.setlength(6.0);
	cout << "lenght of line is" << lin.getlength()<< endl;
	return 0;
}

我们在做题的过程中一般不会主动使用new和delete,只有在题目中要求了,我们才会使用。

——本文转载至资料,仅用于个人学习
——2021年4月19日19:46

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值