【发布时间】:2011-01-25 03:31:17
【问题描述】:
在下面的代码中,基于堆栈的变量“ex”被抛出并被捕获到超出 ex 声明范围的函数中。这对我来说似乎有点奇怪,因为(AFAIK)基于堆栈的变量不能在声明它们的范围之外使用(堆栈已展开)。
void f() {
SomeKindOfException ex(...);
throw ex;
}
void g() {
try {
f();
} catch (SomeKindOfException& ex) {
//Handling code...
}
}
我在 SomeKindOfException 的析构函数中添加了一个 print 语句,它表明 ex 一旦超出 f() 的范围就会被破坏,但是它会在 g() 中被捕获并在它超出范围时再次被破坏.
有什么帮助吗?
【问题讨论】:
-
这里使用引用是否正确?
catch (SomeKindOfException &ex)我认为这很危险,因为它不调用复制构造函数,并且您可以访问属于 f() 的释放堆栈的内存区域!我想这应该是正确的:catch (SomeKindOfException ex) -
通过引用捕获是正确的(甚至更好 - 参见parashift.com/c++-faq-lite/exceptions.html 17.7 节)。正如我对问题的回答所说,被捕获的异常不是抛出的基于堆栈的对象,而是它的副本,它驻留在不同的地方,可以在堆栈展开后幸存下来,因此不存在这样的风险。
-
嗯,我昨天晚上做了一些实验,是的,最好使用参考。看这个:pastebin.com/8YQuNAux 如果你执行它,你会注意到异常在没有引用的情况下在每次捕获时被动态分配(在
new的意义上):如果你使用引用,它只会被分配一次并被破坏范围终止时自动执行。另外我认为这种行为完全取决于编译器。 -
这里详细解释了异常如何工作的一个很好的概述:monoinfinito.wordpress.com/series/exception-handling-in-c
标签: c++ exception exception-handling callstack