使用exit和全局对象

时间:2012-04-30 05:57:33

标签: c++

我有以下程序,我在析构函数中调用exit()。当我在main()中创建一个类型为sample的对象时,析构函数被调用一次并且程序正常退出。但是当我创建一个类型为sample的全局对象时,“Destructing ..”会被无限打印。有人可以解释一下吗?

#include "iostream"
#include "conio.h"

using namespace std;

class sample
{
      public:
     ~sample() {
                    cout <<"Destructing.."<<endl;
                    exit(0);
                }
};

sample obj;

int main()
{
 getch();   
}

3 个答案:

答案 0 :(得分:2)

发生了什么,exit()函数正在让程序在所有全局对象上调用析构函数。因为在你的类的析构函数调用exit(1);时,对象尚未被认为是被破坏的,所以析构函数再次被调用,导致无限循环。

你可以逃脱这个:

class sample {
    bool exiting;
public:
    sample() { exiting = false; }
    ~sample() {
        cout << "Destructing.." << endl;
        if(exiting) return;
        exiting = true;
        exit(0);
    }
};

但是有一个析构函数调用exit()是一个坏主意。考虑其中一种选择:

  • 为退出
  • 创建单独的普通(非析构函数)方法
  • 创建一个运行到&#34;程序&#34;已完成并从main()
  • 调用它
  • 使用abort()代替exit()(感谢金发女郎提到这个)。 abort()绕过通常在调用exit()main()返回时执行的所有清理工作。然而,这也不一定是个好主意,因为程序中的某些清理操作可能非常关键。 abort()仅适用于已经非常糟糕的错误,以至于需要绕过清理。

之前我建议过例,但是记得从析构函数中抛出异常并改变了我的想法。 here's why.

另请注意,行为不一致 - 某些编译器/环境会导致无限循环,有些则不会。归结为在析构函数中的哪一点,对象被认为是被破坏的。我猜这个标准要么没有涵盖这一点,要么说这种情况下的行为是未定义的。

答案 1 :(得分:2)

我同意Micheal Slade的观点,即在析构函数中执行此操作是设计糟糕的标志。但如果您认为自己有充分理由(例如,开发问题),请使用abort()代替exit(0)。这样可以防止任何更多的析构函数被调用并让你退出递归循环。

答案 2 :(得分:1)

你的析构析构函数调用exit,而exit又调用destroy析构函数调用exit然后调用...(是的,它会持续很长时间)。