C++虚析构函数

3
如果我有一个基类和一个派生类,并且在父类中声明了虚析构函数,但实例化了子类对象,当销毁时会调用父类的析构函数(因为是虚函数)吗?如果我还在派生类中声明了析构函数,会同时调用两个析构函数(基类和派生类)吗?提前感谢您的回答 :-)
我的问题的第二部分与第一部分相关。为什么需要在基类中声明虚析构函数?构造函数不是按照层次结构自动调用吗?它们没有共享同一个名称,那么为什么需要这样做呢?难道析构函数不应该默认调用所有的函数吗?此外,通过后期绑定,它能检测到所有的类和对象吗?
编辑:我的问题不仅仅是关于虚析构函数的,而是为什么需要声明虚析构函数,因为它们本来就应该默认被调用。

1
嗯,你的第一段回答了第二段。这在任何一本像样的C++语言书中都有涉及。还有右边相关部分的问题。 - Hans Passant
1
可能是虚拟析构函数是如何工作的?的重复问题。 - Hans Passant
@Hans,我有一本书,但它完全没有被涵盖到。 - rubixibuc
请尝试此链接:https://dev59.com/IHRB5IYBdhLWcg3w77on#15903538 这可能会有所帮助。谢谢。 - Tunvir Rahman Tusher
3个回答

8

是的,父类析构函数会自动调用。

析构函数应该被虚拟化,这样一个派生实例可以被正确地销毁,因为代码认为它有一个基类实例的引用。

在非常有限的情况下,如果你真的需要节省一些vtable查找的时间,不虚拟化也可以。


虚拟关键字在析构函数和拷贝构造函数中是否应用不同?我之所以问拷贝构造函数是因为它是相同概念的一部分。对于成员函数,你只能有一个与类相关的返回类型。所有参数和函数名必须相同。这些其他函数(析构函数和拷贝构造函数)在运行时如何表示?它们是否都有相同的名称,还是按顺序调用?抱歉有这么多问题,只是真的想理解它 :-/. - rubixibuc
基本上,即使名称不同,在继承层次结构中声明析构函数是否会向下传递到所有析构函数? - rubixibuc
是的。构造函数和析构函数的名称不像常规方法名称那样;特殊的classname::classname和classname::~classname语法告诉编译器它是一个构造函数或析构函数,因此继承寻找构造函数/析构函数,而不是特定的classname。 - Phil Lello

4
需要使用虚析构函数是因为多态性。如果你有类似以下的代码:
 class A { ... };

 class B : public A { ... };

 void destroy_class(A* input)
 {
     delete input;
 }

 int main()
 {
     B* class_ptr = new B();
     destroy_class(class_ptr); //you want the right destructor called

     return 0;
 }

虽然这个例子有点刻意,但是当你删除传入的指针时,你希望正确的析构函数被调用。如果class A的析构函数没有声明为virtual,那么只会调用class A的析构函数,而不会调用class B任何派生自class A的类型的析构函数。

在非模板多态数据结构等情况下,这种情况很常见,一个单一的删除函数可能需要删除某个基类类型的指针,实际上指向了一个派生类型的对象。


2

rubixibuc,

是的,子类的析构函数首先被调用,然后是它的超类...然后是它的超类,直到我们到达Object的析构函数。

更多信息:http://www.devx.com/tips/Tip/13059 ... 值得一读...只有一页屏幕,但是这是一篇具有信息量的文章。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接