virtual析构函数 简单的不能再简单的问题,但原理是什么呢?

little_duck 2005-09-02 03:45:32
class str
{
public:
str(){cout<<"构造str \n";}
virtual ~str(){cout<<"~str \n";}//1:为什么这里要+virtual才可以执行析够
virtual f(){cout<<"str f\n";}
};
class nu:public str
{public:
nu(){cout<<"构造nu \n";}
~nu(){cout<<"~nu \n";}
virtual f(){cout<<"nu f\n";}
};
void main()
{
str *z=new nu; //在base class 指向derived class 的时候为什么要把析构函数设置成虚才可以执行虚类析构函数。
delete z;

}

...全文
335 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
zyfire88 2005-09-03
  • 打赏
  • 举报
回复
如果没有virtual将直接析构基类的对象而不会再调用派生类的析构函数
而有了virtual动态帮定它会先调用指针指向类的析构函数,由于他是派生类自然还会调用基类的构造函数
heguosheng 2005-09-03
  • 打赏
  • 举报
回复
mark
tq010or 2005-09-02
  • 打赏
  • 举报
回复
我的理解是:
如果str中的f不为virtual,则容易造成内存泄露,str *z=new nu; delete z; 这样之后系统调用了nu下面的f函数,但是不会默认调用str中的f函数。
一般的做法是把str中的f变成虚函数。这样以后再delete指针的时候就会都析钩掉。
呵呵。
little_duck 2005-09-02
  • 打赏
  • 举报
回复
http://community.csdn.net/Expert/topic/4246/4246799.xml?temp=.3425714
lemon520 2005-09-02
  • 打赏
  • 举报
回复
对象构造的顺序是先基类,再派生类.
析构的顺序是先派生类,再基类.
如果基类没有虚函数,则不存在多态,在用基类指针/引用绑定到一个派生类对象时,该对象就被当成了基类对象,也就是对象被截断了.
所以delete基类指针时,直接调用基类析构函数,从而派生类对象没有得到释放.
为了保证在继承关系中保证派生类可以正确的释放,所以通常把可能要被继承的类的析构函数写成虚拟函数(每个类都会有析构函数).除非你保证该类不会被继承.
而如果有其他成员函数已经是虚拟函数了,那么析构函数是否虚拟都无关紧要了.
little_duck 2005-09-02
  • 打赏
  • 举报
回复
我需要理解的是 知起然,还要知其所以然,我也知道要泄露 但为什么这样 虚拟表如何设置的,如果有virtual base class又会如何等。谢谢
little_duck 2005-09-02
  • 打赏
  • 举报
回复
老大你把effective c++ 的原问抄了一次啊 。
zhouhuahai 2005-09-02
  • 打赏
  • 举报
回复
foochow(恰似你的温柔)都把整个Effective C++的条款搬了出来,汗!

只要这句就够了:

当通过基类的指针去删除派生类的对象,而基类又没有虚析构函数时,结果将是不可确定的。这意味着编译器生成的代码将会做任何它喜欢的事:重新格式化你的硬盘,给你的老板发电子邮件,把你的程序源代码传真给你的对手,无论什么事都可能发生。(实际运行时经常发生的是,派生类的析构函数永远不会被调用
bugebear3 2005-09-02
  • 打赏
  • 举报
回复
More Effective C++里有一条是:

只要类中有一个虚成员函数,那么析构函数就必须声明为Virtual.

不然的话,派生类对象对应的内存空间将得不到释放,造成内存泄漏.
junguo 2005-09-02
  • 打赏
  • 举报
回复
这是编译器的要求,因为如果不设置成虚函数的话,析构函数的解析过程是不确定的。因为z不知道它所指向的子类是哪个类型的,也就不知道该调用什么析构函数。当设置成虚函数的时候,析构函数被保存到了对象z中,就可以知道确切的调用过程了。

你对虚函数在内存中结构熟悉的话,应该很好理解。

64,643

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧