为什么在删除派生类对象时调用基类析构函数(virtual)? [英] Why base class destructor (virtual) is called when a derived class object is deleted?

查看:733
本文介绍了为什么在删除派生类对象时调用基类析构函数(virtual)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

析构函数(当然也是构造函数)和其他成员函数之间的区别是,如果普通成员函数在派生类中有一个主体,那么只有Derived类的版本被执行。而在析构函数的情况下,派生类和基类的版本都被执行?



这将是巨大的知道什么发生在析构函数;



提前感谢!


执行析构函数的主体并销毁任何在本体内分配的自动对象,
a类X的析构函数调用X的直接非变量成员的析构函数, X的直接
基类的析构函数
if X是最导出的类(12.6.2)的类型,它的析构函数调用
X的虚拟基类
的析构函数。所有析构函数都被调用,如果它们被引用一个合法的名字,也就是
忽略任何可能的虚拟覆盖析构函数在更多的派生类。 基础和成员被销毁
,其构造函数完成的顺序
相反(见12.6.2)。
析构函数中的返回语句(6.6.3)可能不会直接返回到调用者;在将控制权转移给调用者之前,调用成员和基础的析构函数
。数组元素的析构函数按照它们的结构中的
的相反顺序调用(见12.6)。


a href =http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization> RAII 资源需要绑定到合适对象的生命周期,并且必须调用各个类的析构函数来释放资源。



例如下面的代码泄漏内存。

  struct Base 
{
int * p;
Base():p(new int){}
〜Base(){delete p; } //必须是virtual
};

struct Derived:Base
{
int * d;
Derived():Base(),d(new int){}
〜Derived(){delete d;}
};

int main()
{
Base * base = new Derived();
//做某事

delete base; //糟糕! 〜Base()被调用(=>内存泄漏)。
}


A difference between a destructor (of course also the constructor) and other member functions is that, if a regular member function has a body at the derived class, only the version at Derived class gets executed. Whereas in case of destructors, both derived as well as base class versions get executed?

It will be great to know what exactly happens in case of destructor (maybe virtual) & constructor, that they are called for all its base classes even if the most derived class object is deleted.

Thanks in advance!

解决方案

The Standard says

After executing the body of the destructor and destroying any automatic objects allocated within the body, a destructor for class X calls the destructors for X’s direct non-variant members,the destructors for X’s direct base classes and, if X is the type of the most derived class (12.6.2), its destructor calls the destructors for X’s virtual base classes. All destructors are called as if they were referenced with a qualified name, that is, ignoring any possible virtual overriding destructors in more derived classes. Bases and members are destroyed in the reverse order of the completion of their constructor (see 12.6.2). A return statement (6.6.3) in a destructor might not directly return to the caller; before transferring control to the caller, the destructors for the members and bases are called. Destructors for elements of an array are called in reverse order of their construction (see 12.6).

Also as per RAII resources need to be tied to the lifespan of suitable objects and the destructors of respective classes must be called upon to release the resources.

For example the following code leaks memory.

 struct Base
 {
       int *p;
        Base():p(new int){}
       ~Base(){ delete p; } //has to be virtual
 };

 struct Derived :Base
 {
       int *d;
       Derived():Base(),d(new int){}
       ~Derived(){delete d;}
 };

 int main()
 {
     Base *base=new Derived();
     //do something

     delete base;   //Oops!! ~Base() gets called(=>Memory Leak).
 }

这篇关于为什么在删除派生类对象时调用基类析构函数(virtual)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆