#include <iostream>
using namespace std;
int main (int argc, char* const argv[]) {
int a = 20;
cout<<"address of a is "<<&a<<endl;
try{
throw a;
}
catch (int& z) {
cout<<"address of z is "<<&z<<endl;
}
return 0;
}
a
的地址与z
的地址不同。这意味着引用在try catch中不起作用。如果没有那么为什么编译器不会产生任何错误?以上代码意味着什么?
答案 0 :(得分:3)
当您抛出任何类型的对象时,标准允许编译器根据需要多次复制对象。因此,在catch
块中,您可能无法获得您投掷的原始对象,而是它可以是另一个对象,它是原始对象的副本,或者是原始对象副本的副本,或者等等。
答案 1 :(得分:2)
我想我的评论不太清楚,所以我写了一些答案。
当您抛出该异常时,您将其按值抛出。这意味着它将被复制(如果它是原始类型或复制对象则无关紧要)。当然,当复制一个对象时,它的内存位置会发生变化(它是一个 new 对象)。为什么这个?因为异常可以展开堆栈以找到正确的catch块。如果你通过引用扔东西你可能得到的是垃圾(因为当变量超出范围时它将被销毁)。我说可能因为实际上编译器不允许抛出引用而你总是有副本。
如果您的异常对象非常大,您可以考虑使用new分配对象,然后抛出其指针。但某人必须解除分配。你准备好冒风险了吗?看一下(例如)MFC上的CException
实现及其Delete()方法(他们试图让这很简单,但我对此并不高兴)。
也许你想知道为什么如果你必须通过引用抓住你的价值。首先是因为它是std::exception
的设计方式(尝试通过值调用>的what()
方法。其次,因为它允许编译器执行某些优化(此外,即使您不使用std :: exception,也不会创建该对象的无用副本)。