基析构函数在派生对象之后调用两次?

发布于 2024-09-05 03:37:04 字数 778 浏览 11 评论 0原文

嘿,为什么在这个程序结束时基析构函数被调用两次?

#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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜是你 2024-09-12 03:37:04

析构函数按顺序调用,就好像它们展开相应构造函数的效果一样。因此,首先是派生对象的析构函数,然后是基对象的析构函数。并且将析构函数设置为虚拟不会对调用/不调用基类析构函数产生任何影响。

另外要提一下,您的示例可以通过这种方式简化(此代码还会导致调用基析构函数两次和派生析构函数一次):

struct A {
   ~A() {
      // ...
   }
};

struct B: A {
   ~B() {
      // ...
   }
};

int main() {
   A a;
   B b;
}

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):

struct A {
   ~A() {
      // ...
   }
};

struct B: A {
   ~B() {
      // ...
   }
};

int main() {
   A a;
   B b;
}
人间☆小暴躁 2024-09-12 03:37:04

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文