默认的catch语句catch(...) {}
如何通过值或引用来捕获异常?
其次,默认抛出throw;
如何通过值或引用抛出异常?
答案 0 :(得分:8)
catch-all catch (...)
根本不能让你访问异常对象,所以这个问题没有实际意义。 [更正:] 使用throw;
重新抛出原始对象。如果处理程序按值捕获,则对本地副本的更改不会影响原始的,重新抛出的对象。 [/] 有关详细信息,请参阅15.3(特别是第17节)。
答案 1 :(得分:2)
你总能抓住你所抛出的东西。 假设你有一个异常类
class MyException { public: int m_data; MyException(int data) { printf("MyException::MyException() ctor\n"); m_data = data; } MyException(const MyException & other) { printf("MyException::MyException() copy ctor\n"); } ~MyException() { printf("MyException::~MyException() dtor\n"); } };
1)如果你抛出一个指针,你将得到指针:
示例1:
void f() { throw new MyException() } void main() { try{ f(); } catch(MyException * ex) // You WILL catch the pointer { delete ex; // You should delete the exception object } catch(MyException & ex) // You WILL NOT catch the pointer { } }
示例2:
void main() { try{ f(); } catch(...) // You WILL catch the pointer, but will be unable to access it { throw; // You are rethrowing the pointer } }
2)如果你抛出了一个对象,你会得到一个对它的引用:
示例1:
void f() { printf("f BEGIN\n"); throw MyException(1); // MyException ctor is called printf("f END\n"); } void main() { printf("main BEGIN\n"); try { f(); } catch(MyException & ex) // You WILL catch a reference to created object { printf("catch MyException: %d\n", ex.m_data); } // MyException dtor is called here!! printf("main END\n"); }
生成以下输出:
main BEGIN
f BEGIN
MyException::MyException() ctor
catch MyException: 1
MyException::~MyException() dtor
main END
示例2:
void main() { try { f(); } catch(...) // You WILL catch a reference to created object, //but will be unable to access it { throw; // You throw the reference } }
答案 2 :(得分:1)
抛出将抛出的值复制到实现定义的位置 因此,值会在throw上复制(这意味着类型必须是可复制的)。
当你抓住时,你可以选择按价值或参考来捕捉。
catch(X val) // Catch by value
{
}
catch(Y& val) // Catch by reference
{
}
为什么要捕获的惯用语是通过const引用来捕获。这是因为如果按值捕获,则可以在将异常从其保存位置复制到catch值时进行切片。如果按值捕获,则会在catch块的末尾销毁该值。保存位置中的副本在try / catch块结束时被销毁(捕获并且不会被重新抛出)。
所以,当你遇到catch(...)
时,没有任何事情发生。异常保留在未指定的位置,该异常已被复制到该异常中。
使用throw重新抛出异常时。 throw;
。再没有任何事情发生,因为异常已经在未指定的位置,并且不需要发生任何事情。
注意:当没有异常传播时调用throw;
是一个错误,将导致调用std :: terminate。