如果函数早期返回或抛出异常,是否会调用对象的析构函数?

时间:2014-09-10 14:53:44

标签: c++ destructor

在下面的代码中,我使用包装器对象将db中的一些内容临时存储在内存中。我的问题很简单:

我能确定调用析构函数吗?我特别担心的情况 a)testCondition为真,函数从构造tempObj的范围的内部范围早期返回 b)在执行此功能期间发生了一些运行时错误(在更高级别捕获)

(作为一个附带问题:这是暂时存储一些数据的好方法吗?在我的应用程序中,someFunc()是当前数据库的保存/导出功能。)

class TempStore
{
public:
    TempStore() {/* delete some stuff from a db and store this in memory*/}
    ~TempStore() {/* write this stuff back into the db*/}
};

void someFunc(bool testCondition)
{
    TempStore tempObj = TempStore();
    // some code
    if (testCondition)
        return; //early return
    // some more code
}

3 个答案:

答案 0 :(得分:6)

当程序离开对象的范围时,将调用自动对象的析构函数。这包括从函数返回(早期或其他),并通过异常离开 - 只要处理异常。如果是异常,则在处理异常之前在堆栈展开期间调用它。

在某些情况下可能不会调用它,包括:

  • 通过致电longjmp离开;这给出了未定义的行为;
  • 通过例外情况离开,但未处理;没有说明堆栈是否已解开。
  • 终止程序(例如,呼叫exit,或引发导致终止的信号)。

答案 1 :(得分:2)

是的,将调用析构函数。如果您提前返回,在堆栈上创建的每个对象都将被正确销毁。如果抛出异常,则在程序执行到达catch块后将调用析构函数。

答案 2 :(得分:2)

除非由于段故障或停电或其他原因导致程序爆炸,否则将调用析构函数。只需从函数中提前返回或抛出异常就不足以阻止析构函数的运行。

这个设计虽然有点缺陷,因为写入数据库是一个可能失败的操作,并且从析构函数中抛出异常是个坏主意。