Who calls the Destructor of the class when operator delete is used in multiple inheritance
这个问题听起来可能太傻了,但是,我在别的地方找不到具体的答案。
对后期绑定的工作方式和继承中使用的虚拟关键字知之甚少。
在代码示例中,当继承的情况下使用指向在堆和删除运算符上创建的派生类对象的基类指针来释放内存时,只有在基析构函数声明为虚函数时,才会按顺序调用派生和基的析构函数。
现在我的问题是:
1)当base的析构函数不是虚的时候,为什么不调用派生dtor的问题只在使用"delete"操作符的情况下出现,为什么不在下面给出的情况下出现:
1 2 3 | derived drvd; base *bPtr; bPtr = &drvd; //DTOR called in proper order when goes out of scope. |
2) When"delete" operator is used, who is reponsible to call the destructor of the class? The operator delete will have an implementation to call the DTOR ? or complier writes some extra stuff ? If the operator has the implementation then how does it looks like , [I need sample code how this would have been implemented].
3) If virtual keyword is used in this example, how does operator delete now know which DTOR to call?
Fundamentaly i want to know who calls the dtor of the class when delete is used.
ZZU1〔1〕
I'm not sure if this is a duplicate, I couldn't find in search.
int main()
{
base *bPtr = new derived();
ZZU1〔2〕
}
号
+一个好问题。
看看虚拟机制是如何为非析构函数方法工作的,你会发现析构函数的行为没有什么不同。
有两种机制在起作用,可能会稍微混淆问题。.首先,一个非虚拟的机制发生在对象的构造和破坏上。对象是按照这个顺序从基类构造到派生类的,并且当销毁时,析构函数的顺序是相反的,因此派生到基类。这里没什么新鲜事。
考虑在派生类对象的基于类指针上调用非虚拟方法,会发生什么?调用基类实现。现在考虑从基类指针调用一个虚拟方法到一个派生类对象,会发生什么?将调用该方法的派生版本。什么都不知道。
现在让我们考虑一下析构函数场景。对具有非虚拟析构函数的派生类对象的基类指针调用Delete。调用了基类析构函数,如果该基类是从另一个类派生的,那么它的析构函数将在下一个类中被调用。因为虚拟机制没有发挥作用,所以不会调用派生的析构函数,因为销毁从您在层次结构中调用的析构函数开始,并一直工作到基类。
现在考虑虚拟析构函数的情况。基于指向派生类对象的类指针调用Delete。在基类指针上调用任何虚方法时会发生什么?将调用派生版本。所以我们的派生类析构函数被调用。在销毁过程中会发生什么,对象从派生析构函数销毁到基类,但这次我们在派生类级别开始销毁,因为是虚拟方法机制。
为什么具有非虚拟或虚拟析构函数的堆栈对象在超出范围时会从派生类析构函数销毁到基类?因为在这种情况下调用声明类的析构函数,而虚拟机制与此无关。
这是因为在这种情况下,编译器知道要销毁的对象的所有信息,在这种情况下,该对象是
当编译器看到
1
2
3
4
5 void fun()
{
Base *base= new Derived();
delete base;
}
但在大多数情况下,它不是,例如这个
1 2 3 4 | void deallocate(Base *base) { delete base; } |
因此编译器不知道要调用哪个析构函数的基或派生。这就是它的工作方式
如果您想了解更多信息,请尝试重载new和delete。
编译器生成所有必要的代码,以正确的顺序调用析构函数,无论它是超出范围的堆栈对象或成员变量,还是正在删除的堆对象。