对象的销毁
- 生活中的对象都是被初始化之后才上市的
- 生活中的对象被销毁前会做一些清理工作
问题:C++中如何清理需要销毁的对象?
添加public的free函数
- 一般而言,需要销毁的对象都应该被清理
- 解决方案:
- 为每个类都提供一个public的free函数
- 对象不需要时立即调用free函数进行清理
class Test
{
int* p;
public:
Test() {p = new int}
void free() {delete p;}
}
存在的问题
- free只是一个普通的函数,必须显示调用
- 对象销毁没有做处理,很可能造成资源泄露
想法:C++编译器能否自动调用某个特殊函数进行对象的清理?
析构函数
- C++的类中可以定义个特殊的清理函数
- 这个特殊的清理函数叫做析构函数
- 析构函数的功能与构造函数相反
- 定义:~ClassName()
- 析构函数没有参数也没有返回值类型,直接推出这个函数不能被重载
- 析构函数在对象销毁时自动被调用
class Test
{
int i;
public:
Test(int v)
{
i = v;
printf("Test(): i = %d\n",i);
}
~Test()
{
printf("~Test(): i = %d\n",i);
}
}
int main()
{
Test t(1);
Test* p = new Test(2);
delete p;
return 0;
}
修改之前的数组类
InrArray.h
#ifndef INTARRAY_H
#define INTARRAY_H
class IntArray{
private:
int m_length;
int* m_pointer;
public:
IntArray(int len);
IntArray(const IntArray& ob);
int length();
bool get(int index, int& value);
bool set(int index, int value);
~IntArray();
};
#endif
IntArray.cpp
#include "IntArray.h"
#include <iostream>
using namespace std;//命名空间声明在此
IntArray::IntArray(int len)
{
m_pointer = new int[len];
for(int i = 0;i < len; i++)
{
m_pointer[i] = 0;
}
m_length = len;
}
IntArray::IntArray(const IntArray& ob)
{
m_length = ob.m_length;
m_pointer = new int[ob.m_length];
for(int i = 0;i < ob.m_length;i++)
{
m_pointer[i] = ob.m_pointer[i];
}
}
int IntArray::length()
{
return m_length;
}
bool IntArray::get(int index, int& value)
{
bool ret = (0 <= index)&&(index < length());
if(ret)
{
value = m_pointer[index];
}
return ret;
}
bool IntArray::set(int index, int value)
{
bool ret = (0 <= index)&&(index < length());
if(ret)
{
m_pointer[index] = value;
}
return ret;
}
IntArray::~IntArray()
{
cout << "~IntArray()" << endl;//在数组类实现细节的代码中加入输入输出,
//必须要有命名空间的声明
delete[] m_pointer;
}
main.c
#include <iostream>
#include "IntArray.h"
using namespace std;
int main(int argc, char *argv[])
{
IntArray a(5);
for(int i=0; i<a.length(); i++)
{
a.set(i,i+1);
}
for(int i=0; i<a.length(); i++)
{
int value = 0;
if(a.get(i,value))
{
cout << "a["<< i<< "]= " <<value << endl;
}
}
IntArray b = a;
for(int i=0; i<b.length(); i++)
{
int value = 0;
if(b.get(i,value))
{
cout << "b["<< i<< "]= " <<value << endl;
}
}
return 0;
}
- 析构函数的定义准则
- 当类中自定义了构造函数并且构造函数中使用了系统资源(如:内存申请,文件打开,等),需要自定义析构函数
小结
- 析构函数是对象销毁时进行清理的特殊函数
- 析构函数在对象销毁时自动被调用
- 析构函数是对象释放系统资源的保障,意义非常重要,可以让我们编写的软件能更加稳定!
Alipay
Wechat