析构函数(destructor)是类成员函数一种
函数的三要素:函数名,形参列表,返回值
1、析构函数原型:
1、无返回值
2、必须和类名一样,但要在前加上~
3、一个类中有且只有一个,不能被重载
2、析构函数作用:
1、如何定义? 如不显式定义,则自动生缺省析构函数
2、何时被调用?当对象消亡时自动被调用
3、有什么作用?它并不是真正意义上删除对象所有内存,而是在删除该对象占用内存之前做一些其他的清理工作,比如,该内部申请了其他内存等等
举个栗子
#includeusing namespace std; class Person { public: Person(): _buf(new char[10]) {} ~Person() { delete _buf; } private: char *_buf; }; int main(int argc, char* argv[]) { Person a; return 0; }
如果没有 ~Person() { delete _buf; } 将会造成内存泄漏
3、析构函数对象的释放顺序
#includeusing namespace std; int COUNT = 1; class Person { public: Person() { _id = COUNT++; cout << "构造函数:" << _id << endl; } ~Person() { cout << "析构函数:" << _id << endl; } private: int _id; }; int main(int argc, char* argv[]) { Person a[3]; return 0; }
有点像栈的方式先进后出
与构造函数相反
了解了以上知识,看看基类析构函数为什么要加上 virtual
二、基类析构函数为什么要加上 virtual用途: 在有继承的时候使用
看以下代码
#includeusing namespace std; // 基类 class Person { public: Person() { cout << "Person 构造函数" << endl; } ~Person() { cout << "Person 析构函数" << endl; } }; // 派生类 class Person_A: public Person { public: Person_A() { cout << "Person_A 构造函数" << endl; } ~Person_A() { cout << "Person_A 析构函数" << endl; } }; // 主函数 int main(int argc, char* argv[]) { Person *a = new Person_A(); delete a; return 0; }
调试结果
可以看到 Person_A 类的析构函数没有被执行
也就是说派生类的析构没有被执行~,非常容易造成内存泄漏
这时候如何改进?
很简单,就是本篇讨论的
基类析构函数为什么要加上 virtual
修改下代码,在基类的析构函数加上 virtual
#includeusing namespace std; // 基类 class Person { public: Person() { cout << "Person 构造函数" << endl; } virtual ~Person() { cout << "Person 析构函数" << endl; } }; // 派生类 class Person_A: public Person { public: Person_A() { cout << "Person_A 构造函数" << endl; } ~Person_A() { cout << "Person_A 析构函数" << endl; } }; // 主函数 int main(int argc, char* argv[]) { Person *a = new Person_A(); delete a; return 0; }
调试结果
可以看到派生类自动调用了析构函数
析构顺序参考上边分析
这就是为什么基类析构函数要加上 virtual
三、_End1234



