基本对象析构函数在退出时被调用吗?

3

我知道这个问题已经被提出了几次,但我正在尝试得到关于上述问题的确定性答案,但我一直遇到矛盾的信息。我需要知道的是,当我使用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;
}

现在如果我从主函数中删除exit(1),那么“Object destroyed”和“Hello”会按预期打印出来。但是,如果将其留在那里,两者都不会被打印。对于“Hello”的原因很明显,但我认为emp1仍然会被销毁,但析构消息没有显示...
我正在查看this link,它提到了静态对象被销毁的问题。那么上述对象是否被视为静态对象?
如果不是,则有没有一种方法可以使程序终止而不会影响内存?我的项目围绕用户输入展开,我试图提供一个选项,如果用户输入单词“exit”,则退出。
if(input_var == "exit")
    {
        cout << "You have chosen to exit the program." << endl;
        exit(1);
    }

这只是我意图的粗略示例。

4个回答

2
根据这个链接,exit函数并不会清除对象。但请注意,如果您使用的是非栈内存,则会调用析构函数:
static employee emp1;

第二个注意点。任何时候在使用 cout 进行调试边缘情况、时间关键的调试等时,您都应该在 cout 之后添加一个 cout.flush(),以确保输出被打印出来后再继续执行。我见过很多人在调试崩溃时使用 cout,但程序终止前操作系统未来得及打印输出内容。


那么,让用户创建的对象以静态方式创建,以便退出时销毁它们,这是否可行?一旦创建对象,唯一能够对其进行的操作就是删除,因此不会有任何值可供更改。 - Dwayne H
1
是的,这是一个选择。您会注意到,如果在声明前面放置static关键字,即使调用exit()函数,构造函数也会被调用。 - jaybers

1
你可以抛出异常。异常将清理未被撤销的范围。
//...
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

我得查一下其中几个东西。我的实际项目有几层函数嵌套,所有这些函数都需要输入,所以这个想法在任何阶段都可行吗?可能作为一个通用的抛出/退出函数,如果他们输入退出,就可以调用它? - Dwayne H
1
异常会一直向外抛出,直到被捕获。通常建议在 main 函数中使用 try{}catch{} 块。这样可以将致命的异常转换为返回值,并简单地 return。完全没有必要使用 exit() - Petr Skocik

1
你的emp1变量是在栈上分配的。 exit不会销毁基于本地栈的变量。

那么有没有一种方法能够安全地使退出选项回到整个程序?我可以创建一个退出函数来销毁动态对象,因为这些对象的数量是固定的,但对于我的非动态对象来说仍然不起作用,因为它们的数量取决于用户创建的数量。 - Dwayne H
1
要么返回到主调用链,要么抛出一个在主函数中被捕获的异常。异常处理将清理所有本地变量。 - 1201ProgramAlarm
我最初尝试了一个返回链,但是它非常难以管理。还有另一个答案提到了抛出异常的方法,所以我会尝试一下,谢谢。 - Dwayne H

1
我需要知道的是当我使用exit()时,基本类对象是否被销毁。你已经证明它不会被销毁,标记为“exit”的os服务会忽略代码问题。请注意,exit在C++之前就存在。
有没有一种方法可以让程序终止而不会影响内存?您已经证明了exit至少是一种在不调用C ++析构函数的情况下终止程序的方法。退出是语言无关的。
a)这意味着内存不会被析构函数修改。
那么内存是否受到破坏?
b)退出(和主要返回)处理的一部分是由操作系统回收该进程的所有内存资源。内存不会被“破坏”(不会调用析构函数,“擦除”或“删除”)。
c)退出的一部分是关闭该进程打开的任何流。 (文件,设备,终端等)
如果b)或c)修改内存,则无法告诉,因为修改与关闭的进程没有更多的关联。

抱歉,我的“被搞糊涂”的意思有点不清楚。我是指在退出情况发生时,调用析构函数时未释放使用的内存。 - Dwayne H
@DwayneH 如果你退出,内存总是(强制)释放的,除非你在一个非常糟糕的操作系统上。 - Petr Skocik
我们在大学使用Linux,但我不知道依赖它是否是一个坏主意。由于我们的成绩取决于许多因素,包括内存管理,尝试其他选项可能更安全,以保持他们的满意度。 - Dwayne H
1
@DwayneH 同意。以一个干净的状态退出是很好的(例如使用valgrind等工具进行测试),因为这意味着您的程序功能可以安全地集成到更大的软件包中。但我建议不要使用非const的全局/静态变量。如果您使用这些变量,除非在这些变量周围有锁定,否则您的函数将无法在多线程环境中正常工作。异常是C++机制,旨在支持对象的适当清理。 - Petr Skocik
@PSkocik 我正在尝试让一个退出函数调用析构函数并使用exit(),这样一切都应该做得正确。我只是卡在了如何让一个向量存储所有创建的东西上。退出的想法只是我想尝试的一些东西,如果我做不到,我就会放弃它。 - Dwayne H

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接