我知道我的析构函数是在堆栈的正常展开和抛出异常时调用的,但不是在调用 exit() 时调用。
还有其他情况我的析构函数不会被调用吗? SIGINT 或 SIGSEGV 等信号怎么样?我认为对于 SIGSEGV,它们不会被调用,但对于 SIGNINT,它们会被调用,我如何知道哪些信号将展开堆栈?
还有其他不被召唤的情况吗?
是否还有其他情况下它们[析构函数]不会被调用?
- 长跳转:这些会干扰自然的堆栈展开过程,并且通常会导致 C++ 中未定义的行为。
- 过早退出(您已经指出了这些,但值得注意的是,由于抛出异常而已经展开堆栈时抛出会导致未定义的行为,这就是为什么我们永远不应该抛出 dtor 的原因)
- 从构造函数抛出不会调用类的 dtor。这就是为什么,如果您在一个构造函数中分配由多个不同指针(而不是智能指针)管理的多个内存块,则需要使用函数级 try 块或避免使用初始值设定项列表并在构造函数中具有 try/catch 块body(或者更好的是,只需使用像scoped_ptr这样的智能指针,因为到目前为止在初始化程序列表中成功初始化的任何成员都将被销毁,即使类dtor不会被调用)。
- 正如所指出的,当通过基指针删除类时未能将 dtor 设为虚拟可能无法调用子类 dtor(未定义的行为)。
- 无法为运算符 new/new[] 调用调用匹配的运算符 delete/delete[](未定义行为 - 可能无法调用 dtor)。
- 在解除分配部分中使用带有自定义内存分配器的新放置时,无法手动调用 dtor。
- 使用像 memcpy 这样的函数,它只将一个内存块复制到另一个内存块,而不调用复制向量。 mem* 函数在 C++ 中是致命的,因为它们会破坏类的私有数据、覆盖 vtable 等。结果通常是未定义的行为。
- 在不完整类型上实例化一些智能指针(auto_ptr),请参阅此讨论 https://stackoverflow.com/questions/12323028/c-destructor-not-being-called-depending-on-the-linking-order
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)