停止执行而不跳过析构函数

Stop execution without skipping destructors

本文关键字:析构函数 执行      更新时间:2023-10-16

是否有可能在不跳过对析构函数调用的情况下终止软件执行?例如,在下面的代码中,由于exit(1)语句,test的析构函数将永远不会被调用。

#include <iostream>
#include <cstdlib>
using namespace std;
class A{
public:
    A(){cout << "Constructed.n";}
    ~A(){cout << "Destroyed.n";}
};
void func()
{
    //Assuming something went wrong:
    exit(1);  
}
int main(int argc, char *argv[])
{
    A test;
    func();
    return 0;
}

我需要的是一种在终止前调用所有必要析构函数的方法来结束程序(从func()内)。到目前为止,我一直通过func()返回值来处理这个问题,如:

bool func()
{
    //Assuming something went wrong:
    return false;
}
int main(int argc, char *argv[])
{
    A test;
    if( !func() )return 1;
    return 0;
}

这个方法的问题是,一旦你需要将它应用于一系列嵌套函数,它很快就会变得非常烦人(和代码膨胀)。

是否有一种方法可以实现第二个示例(适当的析构函数调用)的相同结果,语法类似于第一个示例(无论您在哪里调用exit(1))?

抛出异常,在main中捕获并返回。

你可以依靠堆栈展开:当你想退出时,抛出一个异常并在main()中捕获它。

struct my_exit
{
    int error;
    int operator()()
    {
        // do any cleanup on globals
        return error;
    }
};
int main()
{
    try
    {
        doSomethingThatCouldCauseExit();
    }
    catch (my_exit & me)
    {
        // Clean up globals now
        exit(me());
    }
}

有几种方法可以干净利落地做到这一点。

一个解决方案是使用atexit函数,它在程序终止时简单地调用给定的函数指针。

您必须从堆中分配所有对象,维护一些带有指向所有实例化类实例的指针的全局表,然后在注册函数中迭代表delete中的每个实例。