在什么情况下,都不会调用c++析构函数

In what kind of situation, c++ destructor will not be called?

本文关键字:调用 c++ 析构函数 情况下 在什么      更新时间:2023-10-16

在c++中,我们喜欢在析构函数中做一些事情。但在什么情况下,析构函数不会被调用?

以下情况下的示例:

  1. 线程中的exit()调用
  2. 未处理的异常和退出
  3. TerminateProcess()(在Windows中)
  4. 热/冷重新启动计算机
  5. 计算机突然断电

这是每个C++程序员都应该知道的一种情况:

#include <stdio.h>
class EmbeddedObject {
   private:
      char *pBytes;
   public:
      EmbeddedObject() {
         pBytes = new char[1000];
      }
     ~EmbeddedObject() {
         printf("EmbeddedObject::~EmbeddedObject()n");
         delete [] pBytes;
      }
};
class Base {
  public:
    ~Base(){
       printf("Base::~Base()n");
  }
};
class Derived : public Base {
   private:
      EmbeddedObject emb;
   public:
      ~Derived() {
         printf("Derived::~Derived()n");
      }
};

int main (int argc, const char * argv[])
{
  Derived *pd = new Derived();
  // later for some good reason, point to it using Base pointer
  Base* pb = pd;
  delete pb; 
}

CCD_ 3将被调用,但CCD_。这意味着~Derived()中的代码不执行。它可能必须做一些重要的事情。此外,它的EmbeddedObject的析构函数本应被自动调用,但没有被调用。因此,EmbeddedObject没有机会释放其动态分配的数据。这会导致内存泄漏。

解决方案,使类Base中的析构函数virtual:

class Base {
  public:
    virtual ~Base() {
    }   
};

对上述程序进行这一次更改意味着所有析构函数都将按以下顺序调用:Derived::~Derived()EmbeddedObject::~EmbeddedObject()Base::~Base()

阅读有关析构函数的一般信息。这类问题比你提到的其他情况更可能引起你的关注。例如,在断电的情况下,所有安全清理的赌注通常都会被取消!

在C++中,我们可以很好地控制按照我们希望的顺序强制调用析构函数,这是个好消息。然而,在你编写的程序中,如果你不够小心,你的对象可能会被泄露,根本不会被删除。

对于无限循环范围之外的对象,将不会调用析构函数。

如果创建了一个新放置的对象,则不会自动调用该对象的析构函数。

从所提到的显而易见的事情开始,即exit()、终止信号、电源故障等。

有一些非常常见的编程错误会阻止析构函数被调用。

1) 使用创建对象的动态阵列object* x = new object[n],但用delete x而不是delete[] x; 释放

2) 不是在对象上调用delete(),而是调用free()。当内存通常被释放时,析构函数将不会被调用。

3) 假设您有一个对象层次结构,它本应声明虚拟析构函数,但由于某种原因没有。如果其中一个子类实例在继承结构中被强制转换为不同的类型,然后被删除,它可能不会调用所有的析构函数。

在另一个因抛出异常而被调用的析构函数中抛出异常。