为了账号安全,请及时绑定邮箱和手机立即绑定

为什么有了虚析构函数,就能先调用子类的析构函数

虚函数表的理论已经大概明白了,但是还是搞不懂,在有虚析构函数的情况下,为什么delete父类的指针,会先找到子类的析构函数。

如果是一般的虚函数,因为父类和子类的函数名字都是一样的,调用该函数的时候,通过虚函数表,就会找到子类的函数地址,调用相应的函数。

但是虚析构函数,父类和子类的函数名字是不同的,这样我就想不明白了,delete父类的指针,应该会去找父类的析构函数啊,怎么会先去子类的虚函数表中找到子类的析构函数呢?

正在回答

7 回答

兄弟我在网上看到一种说法,可以解决你的疑惑

总结:虚析构函数的地址存在于虚函数表中,和普通虚函数别无二致,同时也会像普通的虚函数一样进行覆盖

虽然父子的析构函数名字不一样,但是他们占同一个坑(即父子析构函数在虚函数表中的位置是一样的,否则就不存在多态了)

析构时,到特定的坑中调用该类型的析构函数,其析构函数中又嵌套了很多对父类的析构函数的调用

————————————————

版权声明:本文为CSDN博主「F_cff」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/F_cff/article/details/79690470


0 回复 有任何疑惑可以回复我~

兄弟,你的问题我也很疑惑, 子类的虚函数表应该包含父类的虚析构函数和子类的虚拟构函数, 为啥delete的时候调的是子类的虚析构函数呢, 网上的说法都没说清楚, 你现在懂了嘛

0 回复 有任何疑惑可以回复我~

个人理解:CFather *p = new CSon;  父类指针p前四个字节里面装的是虚指针的地址,如果父类有虚析构,那么该指针指向的虚函数列表里第一个元素就是子类的析构函数,当delete p;时,先进入虚函数列表当中执行第一个元素,即子类析构函数,接着再去执行父类本身的析构函数。查看子类虚函数列表当中的元素可以通过如下方式:

pFun pfun =  (pFun)*((int *)*(int *)p + 0);

0 回复 有任何疑惑可以回复我~

问题是两个指针地址值不一样,析构的时候,父类怎么回去寻找得到子类去析构呢?有的话,应该父类应该要存有子类析构函数的地址啊

0 回复 有任何疑惑可以回复我~

我的理解:因为父类指针指向的是子类的对象,因为指针指向的都是首地址,而子类对象的首地址也是虚函数表的位置,所以这个父类指针就找到了子类对象的虚函数表,进而找到虚析构函数。

0 回复 有任何疑惑可以回复我~

我觉得是这样:

虚析构函数,delete父类的指针p,程序会去找父类的指针p指向的地址,该地址就是子类头部虚函数表指针的地址,由指针p找到子类的虚函数表,从而找到子类的虚析构函数。

3 回复 有任何疑惑可以回复我~
#1

慕瓜2376596

这个回答是正确的。你看声明指针的语句 Shape* p = new Circle(); 这里 p指针虽然是用Shape父类声明的,但是他却指向了子类对象Circle; 即:p指向的地址就是:子类头部虚函数表指针的地址。由指针p找到子类的虚函数表,从而找到子类的虚析构函数。
2020-05-29 回复 有任何疑惑可以回复我~

虚函数有动态关联的功能,如果调用基类中的析构函数,而子类中的析构函数却没有被调时,如果自类中有自己的在“堆”上开辟的空间的话,而恰好是在子类的析构函数中完成内存回收的话,这样就会因为没有执行到子类的析构函数,而导致内存泄漏。所以,析构函数与构造函数相反,系统会首先执行子类的析构函数,再执行父类的析构函数。

0 回复 有任何疑惑可以回复我~
#1

bigfire 提问者

兄弟,你没明白我的意思。我不理解的是为什么有了虚析构函数,就能调用到子类的析构函数。这个你了解不?
2016-07-18 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消
C++远征之多态篇
  • 参与学习       66236    人
  • 解答问题       314    个

本教程将带领大家体会面向对象三大特性中的多态特性

进入课程

为什么有了虚析构函数,就能先调用子类的析构函数

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信