当我们抛出一个对象/变量来捕获时会发生什么?

时间:2012-02-22 17:04:36

标签: c++ exception throw rethrow

两个问题 1)当抛出一个Object /变量时会发生什么?比如说,

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&amp; i)//打印2      catch(int i)//打印1

根据我的判断,

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

(即)变量的控制流程实际上并没有抛出中间捕获.....

3 个答案:

答案 0 :(得分:5)

  

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

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

  

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

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

  

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

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

答案 1 :(得分:0)

  

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

关于此的一点说明, 你的内存在dummy_ptr *中不会被释放,你的FILE指针fp *将不会被关闭。

答案 2 :(得分:0)

我认为你不能把它称为变量;它没有名字。但是一个 在确定的未指定位置创建类型为int的新对象 通过实施。当您通过引用捕获时,引用是 绑定到该隐藏的对象。当你从捕获结束时掉下来 阻止,或通过除了重新抛出之外的任何方式离开阻挡块 同样的例外,该对象被“释放”。