【问题标题】:Are Basic Object Destructors Called On Exit()?是否在 Exit() 上调用基本对象析构函数?
【发布时间】:2016-01-23 16:28:57
【问题描述】:

我意识到这个问题已经出现过几次,但我正在努力为上述问题找到一个明确的答案,但我不断遇到相互矛盾的信息。我需要知道的是,当我使用 exit() 时,基本类对象是否被破坏。我知道需要删除动态内存,但我的意思更像是:

#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;

class employee
{
    public:
        employee ();
        string name;
        ~employee();
};

employee::employee () 
{
    name = "bob";
}

employee::~employee()
{
    cout << "Object destroyed" << endl;
}

int main()
{
    employee emp1;
    exit(1);
    cout << "Hello" << endl;
}

现在,如果我从 main 中删除 exit(1),“对象已销毁”和“Hello”将按预期打印。但是,将其保留在那里,两者都没有被打印出来。 “Hello”的原因很明显,但我的印象是 emp1 仍然会被破坏,但没有显示破坏消息......

我在看this link,它说静态对象被破坏。上面的对象不被认为是静态的吗?

如果没有,有没有办法让程序在不占用内存的情况下终止?我的项目围绕用户输入展开,如果用户输入“退出”一词,我试图提供退出选项。

if(input_var == "exit")
    {
        cout << "You have chosen to exit the program." << endl;
        exit(1);
    }

我的意图是一个粗略的例子。

【问题讨论】:

    标签: c++ class destructor exit


    【解决方案1】:

    您的emp1 变量在堆栈上分配。 exit 不会破坏基于本地堆栈的变量。

    【讨论】:

    • 那么有没有办法让退出选项安全地退出整个程序?我可以创建一个退出函数来破坏动态对象,因为创建了一定数量的动态对象,但这仍然不适用于我的非动态对象,因为它们的数量取决于用户制作的数量。
    • 要么将调用链返回到 main,要么抛出 main 中捕获的异常。异常处理将清除所有这些本地人。
    • 我最初尝试了一个返回链,但该死的尝试和管理是地狱。还有另一个答案也提到了抛出异常,所以我会尝试一下,谢谢。
    【解决方案2】:

    根据this link,它不会清理对象。 注意,如果你使用非堆栈内存,它会调用析构函数:

    static employee emp1;
    

    第二个注释。任何时候您使用cout 来调试边缘情况、时序关键调试等,您都应该在cout 之后添加cout.flush(),以确保在继续之前打印您的输出。我见过很多人使用cout 来调试崩溃并且输出永远不会打印,因为程序在操作系统有机会打印输出之前终止。

    【讨论】:

    • 那么让我的用户创建的对象被静态创建是否可行,以便退出破坏它们?一旦对象被制作出来,唯一可以做的就是移除它,所以没有值可以改变。
    • 是的,这是一种选择。你会注意到,如果你把 static 放在声明的前面,即使调用了 exit() 也会调用构造函数。
    【解决方案3】:

    你可以扔。异常将清理展开的范围。

    //...
    int main()
    {
      try{
        employee emp1;
        throw 1; //fake; throwing an object is more advisable in real situations
        cout << "Hello" << endl;
      }catch(int){ 
        exit(1); //or better simply `return 1;`
      }
    }
    

    输出:

    Object destroyed
    

    【讨论】:

    • 我将不得不查找其中的一些内容。我的实际项目深入了几层功能,所有这些都需要输入,那么这个想法在任何阶段都可行吗?可能是一个通用的 throw/exit 函数,如果他们输入 exit 就可以调用它?
    • 异常通过尽可能多的层,直到被捕获。无论如何,通常建议在您的main 函数中有一个try{}catch{} 块。不妨让它将致命异常转换为返回值,并简单地return。根本不需要使用exit()
    【解决方案4】:

    我需要知道的是,当我 使用 exit()。

    你已经证明它不是。标记为“exit”的 os 服务这样做无需担心代码问题。注意 exit 在 C++ 之前就已经存在。

    有没有办法让程序在不搞砸的情况下终止 内存?

    您已经证明 exit 至少是一种无需调用 C++ 析构函数即可终止程序的方法。退出与语言无关

    a) 这意味着内存不会被析构函数修改。

    所以内存被搞砸了?

    b) 退出(和主返回)处理的一部分是该进程的所有内存资源将被操作系统回收。内存不会被“搞砸”(没有调用析构函数,没有“擦除”或“擦除”)。

    c) 退出的一部分是关闭该进程打开的所有流。 (文件、设备、终端等)

    如果b) 或c) 修改内存,你无法分辨,因为修改与关闭的进程没有更多的关联。

    【讨论】:

    • 对不起,我被坑的意思有点不清楚。我的意思是在退出情况发生时调用析构函数不会释放正在使用的内存。
    • @DwayneH 如果你退出,内存总是(强制)释放,除非你在一个非常糟糕的操作系统上。
    • 好吧,我们在 uni 使用 Linux,但我不知道依赖它是否是个坏主意。由于我们正在对包括内存管理在内的许多事情进行评分,因此尝试其他选项中的一个来让他们开心可能会更安全。
    • @DwayneH 同意。以干净的状态退出是很好的(为此使用 valgrind 测试等工具),因为这意味着您的程序的功能可以安全地集成到更大的包中。不过,我建议不要使用非常量全局/静态变量。如果你使用这些,除非你在这些变量周围有锁,否则你的函数将不会很好地放在多线程环境中。例外是 C++ 机制旨在通过适当的清理对象进行备份。
    • @PSkocik 我正在尝试让一个退出函数工作,该函数在使用 exit() 之前调用 destructs,这样一切都应该正确完成。我只是坚持使用矢量来存储创建的所有内容。退出的想法只是我想尝试的事情,如果我做不到,我就放弃它。
    猜你喜欢
    • 2020-04-29
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 2016-03-29
    • 2016-09-26
    相关资源
    最近更新 更多