按值或引用抛出异常

时间:2016-04-20 08:55:38

标签: c++ c++11 exception throw

从这个答案https://stackoverflow.com/a/36738405/4523099

  

没有操作数的throw-expression重新抛出当前处理的内容   例外。使用现有临时值重新激活该例外;   没有创建新的临时异常对象。    - ISO / IEC 14882:2011第15.1节。 8

那么为什么我从这段代码中得到这个结果呢?

#include <iostream>

class my_exception: public std::exception{
public:
    int value;
};
int main()
{
    my_exception ex;
    ex.value=1;
    try{
        throw ex;
    }
    catch(my_exception& e){
        e.value=2;
    }
    std::cout << ex.value;
   return 0;
}

实际结果:

  

1

我认为它应该是2,取决于标准配额。我错过了什么?

2 个答案:

答案 0 :(得分:7)

这是beacuse throw(常规版本)将make a copy

  

首先,从表达式复制初始化异常对象(这可能会调用rvalue表达式的移动构造函数,复制/移动可能会受到复制省略的影响),...

并在内部保留,因此e.value=2;修改内部副本。

在SO中你提到的问题是关于重新投掷的版本,女巫不会制作新副本,而是使用现有的内部副本。

答案 1 :(得分:2)

只有重新抛出(没有操作数)才能重新使用相同的异常对象。以下是一些代码来证明:

#include <iostream>

class my_exception: public std::exception{
public:
    int value;
};

void f(my_exception& ex) {
    ex.value = 1;
    try {
        throw ex;
    } catch (my_exception& e) {
        e.value = 2;
        // Here's the re-throw
        throw;
    }
}

int main()
{
    my_exception ex;
    try {
        f(ex);
    } catch (my_exception& e) {
        std::cout << e.value;
    }
    return 0;
}