1

两个问题 1) 当一个对象/变量被抛出去捕获时会发生什么?比如说,

int foo() {
   FILE *fp = ....;
   int dummy = 10;
   int *dummy_ptr = new int[10];
   throw 1;
}

int main() {
 try {
   foo();
 } catch (int &i) { 
   std::cout<<"ERROR, the value is "<<i<<std::endl;
 }
}

在这种情况下,这里会发生什么?创建一个新变量然后通过???

如果我使用没有引用的指针或变量怎么办

像 catch(int *i) // 或 catch (int i)

此外,是否已释放/关闭范围内声明或启动的所有变量/资源?

2)同样在重新抛出的情况下,如果我打算用引用重新抛出,第二个 catch 将获得一个新变量,如果我在没有引用的情况下重新抛出(即按值),那么中间抛出中所做的更改不受影响……

int goo() {
    throw 2;
}

int foo() {
   try{
      goo();
   } catch(int &i) { // (or) catch(int i) // i is not changing in the next line.
      i = 2;
      throw;
   }
}

int main() {
 try {
   foo();
 } catch (int &i) { 
   std::cout<<"ERROR, the value is "<<i<<std::endl;
 }
}

输出:catch(int &i) // 打印 2 catch(int i) // 打印 1

根据我的判断,

我认为,只要它是参考,如果它在中间步骤中“按值传递”,值就会受到影响。它仍然将原始对象扔给第二个捕获物。

(即)变量的控制流真的不抛出中间捕获.....

4

3 回答 3

5

在这种情况下,这里会发生什么?创建一个新变量然后通过?

是的; 当您抛出一个对象时,它会在某处创建,然后在处理异常后销毁(即在离开catch块后不重新抛出)。

如果我使用没有引用的指针或变量怎么办?在重新抛出的情况下...

如果您按值捕获,那么您将获得该对象的副本 - 如果您重新抛出异常,那么下一个处理程序将获得原始的新副本,并且不会看到您可能所做的任何更改。通过引用捕获将为您提供对抛出对象的引用 - 如果您重新抛出,那么下一个处理程序看到您所做的任何更改。你不能通过指针来捕捉对象——如果指针被抛出,你只会捕捉到一个指针。

另外,在作用域内声明或启动的所有变量是否都已关闭?

当抛出异常时,所有自动变量都被销毁,在范围内throw和所有封闭范围内,直到到达处理程序。不会删除动态分配的变量(例如您的new int[10]) ,并且肯定不会为变量调用诸如此类的任意清理函数,除非它们由基于范围的对象(例如智能指针)管理。fcloseFILE*

于 2012-02-22T17:13:51.963 回答
0

是的,当抛出异常时,所有自动变量都被销毁,在 throw 范围内和所有封闭范围内,直到到达处理程序。

请注意,您的内存dummy_ptr*不会被释放,您的FILE指针fp*也不会关闭。

于 2012-02-22T17:19:41.403 回答
0

我认为您不能将其称为变量。它没有名字。但是int在由实现确定的未指定位置创建了一个新的类型对象。当您通过引用捕获时,引用将绑定到该隐藏对象。当你从 catch 块的末端掉下来,或者以除重新抛出相同异常之外的任何方式离开 catch 块时,对象就会被“释放”。

于 2012-02-22T17:25:36.810 回答