zoukankan      html  css  js  c++  java
  • 虚析构和虚表

       首先给出调用方式

    Base* b = new child;

    child* c = new child;

             第一种情况:基类和子类的析构函数都不是虚函数。

       此种情况下,基类和子类各自调用自己的析构函数。如果直接delete b,则会导致内存空间泄露。(第一句里面,先是new了一个child,child的地址空间包含了[base]+[other]两部分,然后强制赋值给b。由于b是Base类型,无法接收[other]部分,导致[other]指向不明。如果直接调用delete b,则只会释放掉b指向的[base]部分,而new出来的[other]部分则无法释放)

             第二种情况:基类和子类的析构函数都是虚函数

             为Base和child增加虚析构,可以看出b和c都增加了虚表。C的虚表指向自己。b的虚表指向了c的析构函数。因此,调用delete b首先是调用child的析构函数。由于子类析构时会调用基类的析构函数,child的析构函数调用完成后会调用base的析构函数。将new出来的内存空间完全释放。

          值得注意的是,虚表是一个指向“一系列重定向函数入口地址”的指针,也就是说,不管虚表内有几个虚函数,虚表占用的内存空间一定是4字节。比如上图中size_c等于12(C自己的int变量c,从base那里继承来的int变量b,虚表)。

          有趣的是,虽然Base的大小为8字节(自身int变量b,虚表),但实例b为指向子类的指针,跟踪后发现,图2中多出了蓝色框中的内容,我猜大概是为了维护指向的子类信息。而且child加上了[],让我想到了间接寻址或偏移量。如果Base类的实例b自带了子类的信息,为什么不能直接获取子类的类型,还需要Child* p = dynamic_cast(Base*)转换? 

  • 相关阅读:
    用Bootstrap框架弹出iframe页面 在弹出的模态框中载人iframe页面,bootstrapiframe
    Jquery Ajax表单提交插件jquery form用法
    ASP.NET MVC 在控制器中接收视图表单POST过来的数据方法
    RabbitMQ用户管理+VirtualHost管理
    Linux 查看Oracle 信息
    页面元素的坐标位置
    Selenium之Action Chains类
    测试管理:用量化的思想管理工作
    Python selenium ---父子,兄弟,相邻节点定位方式详解
    webdriver 清空input元素的值
  • 原文地址:https://www.cnblogs.com/hgwang/p/5872084.html
Copyright © 2011-2022 走看看