2014-09-10 129 views
3

在下面的代码中,我使用一个包装对象临时存储来自内存中的数据库的一些东西。我的问题很简单:如果函数返回提前或抛出异常,是否会调用对象的析构函数?

我可以确定析构函数被调用吗?我特别担心的是 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 
} 
+0

您是否尝试添加日志(例如printf或写入文件)并进行调试?在你显示的代码中,析构函数将被调用。 – 2014-09-10 14:55:48

+1

运行时错误是什么意思? C++异常?然后它会工作。如果你的程序真的失败了,seg故障等,那么它将无法工作。 – mkaes 2014-09-10 14:57:12

+1

是的,当'someFunc()'函数返回时,假定“正常”程序执行(*例如*没有崩溃或分段错误),'TempStore'的析构函数将被调用。这被称为[“资源获取初始化”(RAII)习语](https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization),它是现代C++的基石。 – 2014-09-10 15:02:05

回答

6

当程序离开对象的作用域时,自动对象的析构函数将被调用。这包括从函数返回(提前或以其他方式),并通过异常退出 - 只要异常得到处理。在例外的情况下,在处理异常之前在堆栈展开期间调用它。

它可能不能被称为在某些情况下,包括:

  • 通过以longjmp呼叫离开;这给出了未定义的行为;
  • 通过未处理的异常离开;没有说明栈是否展开。
  • 终止程序(例如呼叫exit,或产生导致终止的信号)。
2

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

+2

这个答案是不完整的,因此是错误的。从标题:“如果函数崩溃,将调用对象的析构函数吗?“ – 2014-09-10 15:01:10

+1

我认为他说的是异常而非崩溃 – nikitoz 2014-09-10 15:02:40

+0

即使是例外情况,如果代码没有在try块中运行,也不会发生这种情况。 – juanchopanza 2014-09-10 15:02:50

2

将会调用析构函数,除非程序由于seg故障或停电等原因而爆炸。只是简单地从一个函数返回或抛出一个异常不足以阻止析构函数的运行。

尽管这个设计有点不对,因为写入数据库是一种可能失败的操作,并且从析构函数中抛出异常是一个非常糟糕的主意。

+0

您能否建议我如何处理这种情况?如果从析构函数中抛出异常会发生什么? – 2014-09-10 15:11:41

相关问题