程序基石系列(十四) 虚析构函数
来源:互联网 发布:网络短信发送软件 编辑:程序博客网 时间:2024/05/03 11:38
预备知识
用一个例子来说明虚析函数的必要性.在程序清单1中,基类A的构造函数动态分配5个字节,其析构函数负责释放这块内存.派生类Z的构造函数动态分配5000个字节,其析构函数负责释放这块内存.
程序清单1
#include <iostream>using namespace std;class A{ // base classpublic:A(){ cout<<"A() firing"<<endl; p = new char[5]; // allocate 5 bytes}~A(){cout<<"~A() firing"<<endl;delete[] p;// free 5 bytes}private:char *p;};class Z: public A {//derived classpublic:Z(){cout<<"Z() firing"<<endl;q = new char[5000];//allocate 5000 bytes}~Z(){cout<<"~Z() firing"<<endl;delete[] q; //free 50000 bytes} private:char *q;};void f();int main(){for(unsigned i =0; i<3; i++)f();return 0;}void f(){A *ptr; //pointer to base classptr = new Z(); // pointer to derived class objectdelete ptr; //~A() fires but not ~z()}//***** Caution:50000 bytes of inaccessible storage
在main中三次调用f函数:
void f(){A *ptr; //pointer to base classptr = new Z(); // pointer to derived class objectdelete ptr; //~A() fires but not ~z()}//***** Caution:50000 bytes of inaccessible storage由于类A和Z的构造函数与析构函数输出了跟踪信息,程序运行的结果如图所示:
将析构函数声明为虚成员函数可以解决程序清单1中的问题:
class A{ // base classpublic:A(){ cout<<"A() firing"<<endl; p = new char[5]; // allocate 5 bytes}virtual ~A(){cout<<"~A() firing"<<endl;delete[] p;// free 5 bytes}private:char *p;};.......通过定义基类的析构函数~A()为虚成员函数,可以确保其派生类的析构函数也为虚成员函数.为了使代码更清晰,我们可以明确地使用关键字virtual来声明~Z(),不过即使我们不这样做,~Z()仍然为虚成员函数,修改后的程序输出如下图所示:
现在,由于析构函数已经声明为虚成员函数,当通过ptr来删除其所指针的对象时,编译器进行的是运行期绑定.在这里,因为ptr指向一个Z类型的对象,所以~Z()被调用.我们看到随后~A()也被调用了,这是通过将析构函数定义为虚成员函数,我们就保证了在调用f时不会产生内存遗漏.
关于Program Language更多讨论与交流,敬请关注本博客和新浪微博songzi_tea.
0 0
- 程序基石系列(十四) 虚析构函数
- 程序基石系列之自动调用析函数
- 程序基石系列之拷贝构造
- 程序基石系列之类的声明Class declaration
- 程序基石系列之Virtual Funcation and Overload
- 程序基石系列之重载, 覆盖和隐藏
- 程序基石系列之C++多态的前提条件
- 程序人生(十四)
- Redis系列~安全(十四)
- C++编程入门系列之十四(类与对象:构造函数和析构函数)
- C++编程入门系列之十四(类与对象:构造函数和析构函数)
- 单片机小白学步系列(十四) 点亮第一个LED的程序分析
- C++程序员学Java系列之十四:方法(C++喜欢叫函数)
- Python笔记(十四)--函数
- 程序十四
- 程序基石系列之C++运行时类型转换(Runtime Cast)
- 程序设计基石与实践系列之最短的崩溃C语言程序
- 程序设计基石与实践系列之编写高效的C程序与C代码优化
- MySQL unauthenticated user解决办法
- 写在前面
- 用户画像
- 走进小作坊(十九)----商场博弈论的诡计
- C语言中main函数之前可以进行赋值作吗?
- 程序基石系列(十四) 虚析构函数
- hadoop 2 datanode 经常自动挂掉原因
- JDBC学习
- tesklink 管理员项目角色被修改后的解决方法
- 微信公众号开发系列-启用开发模式
- Ruby under Microscope 笔记
- PAT 1017. Queueing at Bank (25)
- 个体革命、去中心化和8090
- android自定义view仿照MIUI中音量控制效果