C++ 在派生对象之后调用了两次基析构函数?
嘿,为什么在这个程序的结尾调用了两次基析构函数C++ 在派生对象之后调用了两次基析构函数?,c++,gcc,polymorphism,virtual-destructor,C++,Gcc,Polymorphism,Virtual Destructor,嘿,为什么在这个程序的结尾调用了两次基析构函数 #include <iostream> using namespace std; class B{ public: B(){ cout << "BC" << endl; x = 0; } virtual ~B(){ cout << "BD" << endl; } void f(){ cout << "BF" << end
#include <iostream>
using namespace std;
class B{
public:
B(){
cout << "BC" << endl; x = 0;
}
virtual ~B(){
cout << "BD" << endl;
}
void f(){
cout << "BF" << endl;
}
virtual void g(){
cout << "BG" << endl;
}
private:
int x;
};
class D: public B{
public:
D(){
cout << "dc" << endl; y = 0;
}
virtual ~D(){
cout << "dd" << endl;
}
void f(){
cout << "df" << endl;
}
virtual void g(){
cout << "dg" << endl;
}
private:
int y;
};
int main(){
B b, * bp = &b;
D d, * dp = &d;
bp->f();
bp->g();
bp = dp;
bp->f();
bp->g();
}
#包括
使用名称空间std;
B类{
公众:
B(){
cout一次调用b,一次调用d
注意:当调用D的析构函数时,它会自动调用B的析构函数,这与普通的虚拟函数不同。在这里,您需要显式调用基类函数来使用它。一旦为B调用它,就为D调用一次
注意:当调用D的析构函数时,它会自动调用B的析构函数,这与普通虚函数不同。在这里,您需要显式调用基类函数来使用它。析构函数是按顺序调用的,就好像它们正在解除相应构造函数的效果一样。因此,首先是派生obj的析构函数然后是基对象的析构函数。使析构函数虚拟化对调用/不调用基类析构函数没有任何影响
同样值得一提的是,您的示例可以通过这种方式简化(这段代码还导致两次调用基本析构函数,一次调用派生析构函数):
析构函数是按顺序调用的,就好像它们在释放相应构造函数的效果一样。因此,首先是派生对象的析构函数,然后是基对象的析构函数。将析构函数设置为虚拟对调用/不调用基类析构函数没有任何影响
同样值得一提的是,您的示例可以通过这种方式简化(这段代码还导致两次调用基本析构函数,一次调用派生析构函数):
但是virtual~D()被称为giving me dd。为什么它会返回并再次执行?(意思是基类)所以virtual~D()会给出dd和BD,然后virtual~B()会给出另一个BD correct?。很抱歉让人讨厌lol:)@sil3nt:如果我正确理解了你的问题/困惑,这有帮助吗:基析构函数(BD)在同一个对象上调用两次,但不是两次。当B被销毁时调用一次,当D被销毁时调用一次。正如其他人所提到的,当D被销毁时,基类B的析构函数也会被自动调用。因此,您看到B析构函数为两个不同的对象分别调用了一次,因此是两次——而不是两次r一个对象。但是virtual~D()被称为giving me dd。为什么它会返回并再次执行?(意思是基类)所以virtual~D()给出dd和BD,然后virtual~B()给出另一个BD correct?很抱歉让人恼火lol:)@sil3nt:如果我正确理解了你的问题/困惑,这有帮助吗:基析构函数(BD)在同一个对象上调用两次,但不是两次。当B被销毁时调用一次,当D被销毁时调用一次。正如其他人所提到的,当D被销毁时,基类B的析构函数也会被自动调用。因此,您看到B析构函数为两个不同的对象分别调用了一次,因此是两次——而不是两次r一个对象。因为有两个基本对象。一个直接b另一个包裹在派生d中。最后需要销毁两个。因为有两个基本对象。一个直接b另一个包裹在派生d中。最后需要销毁两个。
struct A {
~A() {
// ...
}
};
struct B: A {
~B() {
// ...
}
};
int main() {
A a;
B b;
}