C++入门——(类的默认成员函数)析构函数
文章目录
- 一、析构函数
- 二、析构函数的特点
- 总结
一、析构函数
析构函数与构造函数功能相反,析构函数不是完成对对象本⾝的销毁,⽐如局部对象是存在栈帧的,函数结束栈帧销毁,他就释放了,不需要我们管,C++规定对象在销毁时会⾃动调⽤析构函数,完成对象中资源的清理释放⼯作。析构函数的功能类⽐我们之前Stack实现的Destroy功能。
二、析构函数的特点
- 1.析构函数名是在类名前加上字符
~
。- 2.⽆参数⽆返回值。 (这⾥跟构造类似,也不需要加void)
关于构造函数,请看博主之前构造函数的文章
构造函数- 3.⼀个类只能有⼀个析构函数。若未显式定义,系统会⾃动⽣成默认的析构函数。
class Stack
{
public:
//全缺省的默认构造函数
Stack(int n = 4)
{
_a = (int*)malloc(n * sizeof(int));
_capacity = n;
_top = 0;
}
//析构函数
~Stack()
{
}
private:
int* _a;
int _capacity;
int _top;
};
- 4.对象⽣命周期结束时,系统会⾃动调⽤析构函数。
class Stack
{
public:
//全缺省的默认构造函数
Stack(int n = 4)
{
_a = (int*)malloc(n * sizeof(int));
_capacity = n;
_top = 0;
}
//析构函数
~Stack()
{
cout << "~Stack()" << endl;//并非析构函数就是打印,这里只是为了看的更清楚
}
private:
int* _a;
int _capacity;
int _top;
};
int main()
{
Stack st;
return 0;
}
注意看,在main函数中我们并没有调用析构函数~Stack,但是打印了结果。这说明析构函数确实是自动调用的。
这里将析构函数写成了打印的形式,是为了更加直观的感受它的自动调用,而不是析构函数就是打印。
真正的析构函数:(类似于C语言定义栈的destroy函数)
//析构函数
~Stack()
{
//cout << "~Stack()" << endl;
free(_a);
_a = nullptr;
_top = _capacity = 0;
}
- 5.跟构造函数类似,我们不写编译器⾃动⽣成的析构函数对内置类型成员不做处理,⾃定类型成员会调⽤他的析构函数。
自定义类型和内置类型,同样在构造函数那一章有写。
- 6.还需要注意的是我们显⽰写析构函数,对于⾃定义类型成员也会调⽤他的析构,也就是说⾃定义类型成员⽆论什么情况都会⾃动调⽤析构函数。
比如两个栈实现队列时,我们队列不写析构函数,在程序结束时,也会去自动调用栈的析构函数。
class Stack
{
public:
//全缺省的默认构造函数
Stack(int n = 4)
{
_a = (int*)malloc(n * sizeof(int));
_capacity = n;
_top = 0;
}
//析构函数
~Stack()
{
cout << "~Stack()" << endl;
free(_a);
_a = nullptr;
_top = _capacity = 0;
}
private:
int* _a;
int _capacity;
int _top;
};
//定义队列的结构
class MyQueue
{
Stack _pushst;
Stack _popst;
};
int main()
{
MyQueue q;
return 0;
}
由运行结果可以看到,程序中并没有调用MyQueue的析构函数,但打印了两次~Stack(),也就是说调用了两次Stack的析构函数
如果我们写了,依旧会去调用Stack的析构函数:
class Stack
{
public:
//全缺省的默认构造函数
Stack(int n = 4)
{
_a = (int*)malloc(n * sizeof(int));
_capacity = n;
_top = 0;
}
//析构函数
~Stack()
{
cout << "~Stack()" << endl;
free(_a);
_a = nullptr;
_top = _capacity = 0;
}
private:
int* _a;
int _capacity;
int _top;
};
//定义队列的结构
class MyQueue
{
public:
~MyQueue()
{
cout << "~MyQueue()" << endl;
}
private:
Stack _pushst;
Stack _popst;
};
int main()
{
MyQueue q;
return 0;
}
从运行结果可以看到,既调用了MyQueue的析构函数,也调用了Stack的析构函数
- 7.如果类中没有申请资源时,析构函数可以不写,直接使⽤编译器⽣成的默认析构函数,如Date;
如果默认⽣成的析构就可以⽤,也就不需要显⽰写析构,如MyQueue;
但是有资源申请时,⼀定要⾃⼰写析构,否则会造成资源泄漏,如Stack。
class Date
{
public:
构造函数,类名就是函数名
函数没有返回值,所以函数没有类型
//构造函数也可以写成缺省参数
Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
private:
// 这⾥只是声明,没有开空间
// 不需要析构函数
int _year;
int _month;
int _day;
};
- 8.⼀个局部域的多个对象,C++规定后定义的先析构。
#include<iostream>
using namespace std;
class Date
{
public:
//构造函数也可以写成缺省参数
Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
~Date()
{
cout << "~Date()" << endl;
}
void Print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
private:
// 这⾥只是声明,没有开空间
int _year;
int _month;
int _day;
};
class Stack
{
public:
//全缺省的默认构造函数
Stack(int n = 4)
{
_a = (int*)malloc(n * sizeof(int));
_capacity = n;
_top = 0;
}
//析构函数
~Stack()
{
cout << "~Stack()" << endl;
free(_a);
_a = nullptr;
_top = _capacity = 0;
}
private:
int* _a;
int _capacity;
int _top;
};
class MyQueue
{
public:
~MyQueue()
{
cout << "~MyQueue()" << endl;
}
private:
Stack _pushst;
Stack _popst;
};
int main()
{
Date d1;
Stack st;
MyQueue q;
return 0;
}
注意这里先定义的是d1,但却是最后调用析构函数的。
总结
以上就是今天要讲的内容,本文介绍了C++中默认成员函数的析构函数,其余默认函数,请关注后续文章。