3

如果我有一个基类和一个派生类,并且我在父虚拟中删除了析构函数,但实例化了一个子类类型的对象,那么在销毁时它会调用父析构函数吗(因为是虚拟的)?如果我还在派生类中声明了一个析构函数,它会同时调用两个析构函数(基类和派生类)。提前致谢 :-)。

我的问题的第二部分是关于第一部分。为什么基类析构函数需要声明为virtual。不要构造函数在层次结构中循环。他们不共享相同的名字,那么哪里需要它?它不应该对析构函数起作用吗,或者默认情况下只有一个被调用?另外通过后期绑定是否能够检测到所有的类和对象是由什么组成的?

编辑:我的问题不仅仅是关于虚拟析构函数,而是为什么它需要被声明为虚拟的,因为它们都应该被默认调用。

4

3 回答 3

8

是的,父析构函数将被自动调用。

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

非常有限的情况下,如果您确实需要在 vtable 查找上节省几个周期,则可以不进行虚拟化。

于 2011-04-26T04:45:17.847 回答
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;
 }

虽然有点人为的例子,当您删除destroy_class()函数的传入指针时,您希望调用正确的析构函数。如果class A未声明for 的析构函数virtual,则只会调用 for 的析构函数,class A不会调用 for 的析构函数class B或任何其他派生类型class A

像这样的东西通常是非模板多态数据结构等的事实,其中单个删除函数可能必须删除某些实际指向派生类型对象的基类类型的指针。

于 2011-04-26T04:45:09.627 回答
2

鲁比布克,

是的,首先调用子类析构函数,然后是超类……然后是超类,依此类推,直到我们到达 Object 的析构函数。

更多在这里: http: //www.devx.com/tips/Tip/13059 ...值得一读...只有全屏,但它是一个信息丰富的全屏。

于 2011-04-26T04:47:22.363 回答