使用 exit 和全局对象
Posted
技术标签:
【中文标题】使用 exit 和全局对象【英文标题】:Using exit and a global object 【发布时间】:2012-04-30 05:57:33 【问题描述】:我有以下程序,我在析构函数中调用 exit()。当我在 main() 中创建一个 sample 类型的对象时,析构函数被调用一次并且程序正常退出。但是当我创建一个样本类型的全局对象时,“Destructing..”会被无限打印出来。谁能解释一下?
#include "iostream"
#include "conio.h"
using namespace std;
class sample
public:
~sample()
cout <<"Destructing.."<<endl;
exit(0);
;
sample obj;
int main()
getch();
【问题讨论】:
可能你使用的是turboc,请避免使用,不要使用conio.h函数。 M 使用 Dev-C++ 。它使用 GCC 编译器 【参考方案1】:发生的事情是,exit()
函数正在让程序调用所有全局对象的析构函数。并且由于在您的类的析构函数调用exit(1);
时,该对象还没有被认为是被析构的,析构函数被再次调用,导致无限循环。
你可以摆脱这个:
class sample
bool exiting;
public:
sample() exiting = false;
~sample()
cout << "Destructing.." << endl;
if(exiting) return;
exiting = true;
exit(0);
;
但是调用 exit()
的析构函数是个坏主意。考虑以下备选方案之一:
main()
调用它
使用abort()
而不是exit()
(感谢金发姑娘提到这一点)。 abort()
绕过通常在调用exit()
和main()
返回时完成的所有清理工作。然而,这也不一定是一个好主意,因为程序中的某些清理操作可能非常关键。 abort()
仅适用于已经严重到需要绕过清理的错误。
我之前建议过异常,但记得从析构函数内部抛出异常并改变了主意。 here's why.
另请注意,行为并不一致 - 一些编译器/环境会导致无限循环,而另一些则不会。它归结为在析构函数中的哪个点对象被认为被销毁。我猜这个标准要么没有涵盖这一点,要么说这种情况下的行为是未定义的。
【讨论】:
为什么我没有得到与提问者相同的效果? 因为你的编译器可能更聪明 即使使用-O0
和gcc
,我也会打印一行。
另外,如果它为全局打印多行,那为什么不本地呢。
本地析构函数在其函数退出时被调用。我将展开以涵盖这一点。【参考方案2】:
我同意 Micheal Slade 的观点,即在析构函数中这样做是糟糕设计的标志。但是,如果您认为您有充分的理由这样做(例如,开发问题),请使用abort()
而不是exit(0)
。这将阻止调用任何更多的析构函数并让您退出递归循环。
【讨论】:
【参考方案3】:您的破坏性析构函数调用 exit 进而调用破坏析构函数调用 exit 进而调用 ...(是的,它会持续很长时间)。
【讨论】:
以上是关于使用 exit 和全局对象的主要内容,如果未能解决你的问题,请参考以下文章