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

对析构函数的疑惑

疑问1、有个问题啊老师, 程序在执行delete p;这个语句时,为什么会根据 p 指针找到相应的子类对象的虚函数表指针啊;

疑问2、 还有一个问题,就是-- 如果基类中没有虚函数,为什么使用 delete p; 还是不能调用指针P 对应子类对象的析构函数啊!

针对疑问2自己试验的代码如下:

#include <iostream>
using namespace std;

class Shape
{
public:
Shape(){ cout << "Shape()\n";}
~Shape() { cout << "~Shape()\n"; }
int x;
int y;
};

class Circle : public Shape
{
public:
Circle(){ cout << "Circle()\n";}
~Circle() { cout << "~Circle()\n";}
};

int main()
{
Shape *p = new Circle;
delete p;
p = NULL;
return 0;
}

运行结果如下:

http://img1.sycdn.imooc.com//56eba0c70001419604640150.jpg





此时,还是没有调用子类Circle 中的析构函数。

这节课老师讲的基类中都有虚函数,而此时基类中没有虚函数,子类中的析构函数还是不能调用。到这里就有困惑了,还望老师予以解答。。。谢谢您

正在回答

3 回答

你提的问题在于,没有虚函数时,指针p指向Shape 类对象的指针变量,即使让它指向了Circle,但实际上p指向的是Circle中从基类继承的部分,通过指向基类对象的指针,只能访问派生类中的基类成员,而不能访问派生类增加的成员,所以只会执行基类的析构函数

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

1、虚函数表不是只存储虚函数的地址吗? 怎莫理解您说的 “类对象的头部即虚函数表所在” 这句话。

虚函数表存放的是虚函数的地址,虚函数表指针存放的是虚函数表的首地址,在内存中,子类对象Circle头部(即前四个字节存放的是虚函数表指针,父类指针p指向子类Circle,也就是说把子类Circle的首地址赋值给p,根据p就可以找到子类Circle的虚函数表指针,依次找到虚函数表,再找到虚函数。


2、没有虚函数,就没有虚函数表,子类对象Circle头部(即前四个字节)就没有虚函数表指针,就没法调用子类对象Circle的析构函数

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

1、虚函数表位于每个含虚函数对象存储位置的头部即对象指针p指向的位置,虽然p是父类类型的指针,但是赋值时指向的是子类对象,也就是子类对象的头部即虚函数表所在

2、这个现象的出现就是我们要用虚析构函数的原因(不知道如何说明==)

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

Popper0912 提问者

虚函数表不是只存储虚函数的地址吗? 怎莫理解您说的 “类对象的头部即虚函数表所在” 这句话。
2016-03-18 回复 有任何疑惑可以回复我~
#2

丿琴丶殇 回复 Popper0912 提问者

首地址?
2016-08-28 回复 有任何疑惑可以回复我~

举报

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

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

进入课程

对析构函数的疑惑

我要回答 关注问题
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号