什么是析构函数
如果说构造函数是对象来到世间的第一声哭泣,那么析构函数就是对象死亡前的最后遗言。
析构函数在对象销毁时会被自动调用,完成的任务是归还系统的资源。
特性:
1、如果没有自定义的析构函数,则系统自动生成
2、析构函数在对象销毁时自动调用
3、析构函数没有返回值、没有参数也不能重载
定义格式
~类名()
例如:
class Student { public: Student() {cout<<"Student"<<endl;} ~Student() {cout<<"~Student"<<endl;} // 析构函数不允许加任何参数 private: string m_strName; }
定义析构函数的必要性
class Student { public: Student() {m_pName = new char[20];} ~Student() {m_pName = new char[20];} private: char *m_pName; }
我们在定义 m_pName 这个变量时,没有用string类型的数组,而是用char类型的指针,并且在函数的定义中,我们把这个指针指向了一个堆中的内存。当这块空间被使用完后,如果没有被释放,那么就会造成内存的泄漏。要释放掉这些内存的最好时机就是在对象被销毁之前。
代码示例
#include <iostream> #include <stdlib.h> #include <string> #include "Teacher.h" using namespace std; /************************************************************************* Teacher类 自定义析构函数 普通方式实例化对象,在销毁对象时是否自动调用析构函数 通过拷贝构造函数实例化对象,在销毁对象时是否自动调用析构函数 数据成员: 姓名 年龄 成员函数: 数据成员的封装函数 *************************************************************************/ class Teacher { public: // 声明构造函数,参数给定默认值 Teacher(string name = "cjj",int age = 22); // 声明拷贝构造函数 Teacher(const Teacher &tea); // 声明析构函数 ~Teacher(); // 声明成员函数,把所有的成员函数都罗列出来 void setName(string _name); string getName(); void setAge(int _age); int getAge(); private: string m_strName; int m_iAge; }; // 定义构造函数,使用初始化列表,初始化构造函数的参数 Teacher::Teacher(string name,int age):m_strName(name),m_iAge(age) { cout << "Teacher(string name,int age)" << endl; } // 定义拷贝构造函数 Teacher::Teacher(const Teacher &tea) { cout<<"Teacher::Teacher(const Teacher &tea)"<<endl; } // 定义析构函数 Teacher::~Teacher(){cout<<"证明析构函数被调用"<<endl;} // 类外定义,写出成员函数的函数体 void Teacher::setName(string _name) { m_strName = _name; } string Teacher::getName() { return m_strName; } void Teacher::setAge(int _age) { m_iAge = _age; } int Teacher::getAge() { return m_iAge; } int main(void) { Teacher t1; // 从栈中实例化对象 Teacher *p = new Teacher(); // 从堆中实例化对象 delete p; Teacher t2(t1); system("pause"); return 0; }