`
zhangziyueup
  • 浏览: 1165377 次
文章分类
社区版块
存档分类
最新评论

思考virtual析构

 
阅读更多

Author:zfive5(zhaozidong)

Email:zfive5@yahoo.com.cn

最近同住的朋友忙着找工作,他C++的问题看了一堆,我也受其影响复习了一些C++知识, virtual析构听他说“点播率还挺高的”,所以拿来仔细研究,求个深解!

首先,定义3个类,注意了析构函数的virtual 说明

class ZF5_1

{

public:

ZF5_1()

{

}

virtual ~ZF5_1()

{

printf("Hello ZF5_1/r/n");

}

};

class ZF5_2:public ZF5_1

{

public:

ZF5_2()

{

};

virtual ~ZF5_2()

{

printf("Hello ZF5_2/r/n");

};

};

class ZF5_3:public ZF5_2

{

public:

ZF5_3()

{

};

virtual ~ZF5_3()

{

printf("Hello ZF5_3/r/n");

};

};

然后执行代码:

ZF5_1 *p5=new ZF5_3;

delete p5;

1.如果都有virtual

输出:

Hello ZF5_3

Hello ZF5_2

Hello ZF5_1

2.如果都去掉virtual

输出:

Hello ZF5_1

3.如果只去掉ZF5_2virtual

输出:

Hello ZF5_3

Hello ZF5_2

Hello ZF5_1

第一种情况

虽然delete是基类指针,但由于有virtual析构声明,所以delete调用的派生类的析构(派生类用自己的析构函数指针重写虚函数表),然后派生类析构完成后再调用直接基类析构(C++就是这样规定的,编译器隐含这个过程,通过看汇编代码,一切机理ok),这样一级级的调用,就出现了第一种输出!

第二种情况

由于没有virtual修饰,所以delete调用是默认的ZF5_1析构,出现第二种输出就理所当然了。

第三种情况

由于ZF5_1virtual修饰,所以以后所有它的派生类用自己的析构函数指针重写虚函数表里的对应的位置,以至出现与第一种情况相同的结果!

有一种情况没有表达,就是如果定义如下:

virtual ZF5_1

ZF5_2

ZF5_3

ZF5_4

ZF5_2 *p1=new Z5_4;

delete p1;

输出:

Hello ZF5_4

Hello ZF5_3

Hello ZF5_2

Hello ZF5_1

这种情况在VC6下,只要有基类virtual声名,以后的派生类都自动加上virtual,不知道gcccb是怎样处理这种情况的!有机会验证一下,对了很有可能是C++标准规定,看来还得先去翻翻C++ Primer了。

ZF5_3析构完成后默认调用ZF5_2析构汇编代码:(VC6环境下)

52: ~ZF5_3()

53: {

004013E0 push ebp

004013E1 mov ebp,esp

004013E3 sub esp,44h

004013E6 push ebx

004013E7 push esi

004013E8 push edi

004013E9 push ecx

004013EA lea edi,[ebp-44h]

004013ED mov ecx,11h

004013F2 mov eax,0CCCCCCCCh

004013F7 rep stos dword ptr [edi]

004013F9 pop ecx

004013FA mov dword ptr [ebp-4],ecx

004013FD mov eax,dword ptr [ebp-4]

00401400 mov dword ptr [eax],offset ZF5_3::`vftable' (00423044)

54: printf("Hello ZF5_3/r/n");

00401406 push offset string "Hello ZF5_3/r/n" (00424050)

0040140B call printf (00401e40)

00401410 add esp,4

55: };

00401413 mov ecx,dword ptr [ebp-4]

00401416 call @ILT+145(ZF5_2::~ZF5_2) (00401096)

0040141B pop edi

0040141C pop esi

0040141D pop ebx

0040141E add esp,44h

00401421 cmp ebp,esp

00401423 call __chkesp (00401e00)

00401428 mov esp,ebp

0040142A pop ebp

0040142B ret

分享到:
评论

相关推荐

    C++析构函数使用virtual的原因

    C++析构函数使用virtual的原因

    VirtualXposed_0.20.2.apk

    VirtualXposed 是基于VirtualApp 和 epic 在非ROOT环境下运行Xposed模块的实现(支持5.0~10.0)。 与 Xposed 相比,目前 VirtualXposed 有两个限制: 不支持修改系统(可以修改普通APP中对系统API的调用),因此...

    Virtual Serial Port Driver 7.2.308 + vspdctl.dll 激活

    Virtual Serial Port Driver 7.2.308 + vspdctl.... The applications can exchange data on virtual ports through virtual null-modem cable. The data sent from one port to another will be received momentarily.

    Android代码-VirtualApp

    VirtualApp is an open platform for Android that allows you to create a Virtual Space, you can install and run apk inside. Beyond that, VirtualApp is also a Plugin Framework, the plugins running on ...

    virtuallab使用说明

    virtual lab的说明书,详细介绍virtuallab的使用,附带一些例子

    Virtual.Serial.Port.Driver(免安装版)

    Virtual.Serial.Port.Driver(免安装版)Virtual.Serial.Port.Driver(免安装版)Virtual.Serial.Port.Driver(免安装版)Virtual.Serial.Port.Driver(免安装版)Virtual.Serial.Port.Driver(免安装版)Virtual....

    VirtualLab Fusion 2020 下载链接及使用说明

    VirtualLab Fusion 2020 下载链接及使用说明

    VirtualTreeView V6.3

    本资源中含VirtualTreeView V6.3和V5.5.3全部文件,另加PDF格式的使用说明(810页)。 V6.X Embacadero's RAD Studio XE3 - 10.1 Berlin V5.X Delphi7 - Delphi XE8 (本资源含VirtualTreeView V5.5.3) Virtual ...

    react-virtual-list:超简单的虚拟化列表React组件

    react-virtual-list允许您显示固定高度项目的大列表,而仅使这些项目在屏幕上可见。 这允许使用少得多的DOM元素呈现大列表。其他好处: 一个依赖项(它是prop-types ) 性能-演示页面几乎总是保持60fps以上的速度 将...

    lms virtual.lab13本地帮助的VBA部分

    利用LMS Virtual.Lab Motion中基于VBA的日志和脚本功能,可对任意操作过程进行记录和复现。基于VBA的二次开发功能是LMS Virtual.Lab Motion的另一个突出优点。通过该功能,工程师在LMS Virtual.Lab Motion框架内部或...

    Fabula_Virtual-Serial-Port-Kit.v5.5.1_Keygen.zip

    它跟Eltima VSPD(Virtual Serial Port Driver)的功能类似,厂商不同,Fabula公司的软件。这是当前最新版本,带注册机。http://www.fabulatech.com/virtual-serial-port-kit.html ,Create virtual serial ports and ...

    VirtualLab7.3试用版

    VirtualLab的优势:光学混合仿真能力很强,上手也很简单,功能相对丰富。缺点,正式版好像还没出来,有一些小的bug,但是能忍。 注意:试用版最大的问题,不能保存仿真结果,也不能导出仿真结果,只能截图。。。

    VirtualBreadboard/vjredist

    VirtualBreadboard安装包和vjredist安装包.一款模拟Arduino开发环境的软件,非常适合刚入门的开发者使用。

    virtual_audio_cable安装失败问题

    virtual_audio_cable安装失败:以前安装过virtual_audio_cable,卸载不完全导致的安装失败

    virtual lab

    virtual lab 基础培训教程,声学边界元

    LMS+Virtual.Lab+13.6+安装说明

    LMS+Virtual.Lab+13.6+安装说明 详细介绍LMS+Virtual.Lab+13.6安装流程

    HP Integrity Virtual Machines installation Guide

    This document describes how to install and configure the HP Integrity Virtual Machines (Integrity VM) product, and how to create and install virtual machines and guest operating systems. Refer to the ...

    VirtualXposed-0.20.3已编译完整包

    VirtualXposed是一个开源框架,也是一个如同Android下的虚拟机,也有人说它是一个APP盒子。那么它能干些什么?APP分身、APP多开、避开硬件资源限制、一些APP嫁接后实现补丁外挂等等。 (1)由于CSDN上传资源最大不...

    Virtual Serial Port Driver Pro V9.0.270 专业破解版 虚拟串口

    Virtual Serial Port Driver Pro(虚拟串口工具)是一款功能非常专业的虚拟串口辅助软件。压缩包内有破解说明,旧版本的win10用着好像有些兼容问题,于是到官网看看,发现已经更新到9.0版本了,还分为专业版和标准版,...

    virtual pdf printer破解

    virtual pdf printer破解 这个用于WORD向PDF的转化非常好用,排版好以后直接转换就行了! http://blog.csdn.net/zjt289198457/article/details/7046533 这是一个使用方法的链接! 祝你好运!

Global site tag (gtag.js) - Google Analytics