基析构函数在派生对象之后调用两次?
嘿,为什么在这个程序结束时基析构函数被调用两次?
#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();
}
hey there, why is the base destructor called twice at the end of this program?
#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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
析构函数按顺序调用,就好像它们展开相应构造函数的效果一样。因此,首先是派生对象的析构函数,然后是基对象的析构函数。并且将析构函数设置为虚拟不会对调用/不调用基类析构函数产生任何影响。
另外要提一下,您的示例可以通过这种方式简化(此代码还会导致调用基析构函数两次和派生析构函数一次):
Destructors are called in order, as if they were unwinding the effects of the corresponding constructors. So, first the destructors of the derived objects, then the destructors of the base objects. And making the destructors virtual doesn't have any impact on calling / not calling the base class destructor.
Also to mention, your example could be simplified this way (this code also results in calling the base destructor twice and the derived destructor once):
b 调用一次,d 调用一次
注意,当调用 D 的析构函数时,它会自动调用 B 的析构函数,这与普通的虚函数不同。您需要显式调用基类函数才能使用它。
Once it is called for b and once for d
Note when destructor of D called it is automatically calls the destructor of B it is different from ordinary virtual functions. where you need explicitly call base class function to use it.