Obsługa wyjątków - ponowne rzucenie wyjątku

0

Cześć, mam takie przypadki:

try{
//cos tam
}catch(Ex e){
  throw;
}

oraz

try{
//cos tam
}catch(Ex e){
  throw e;
}

Czym różnią się te 2 fragmenty? tzn z tego co szukałem to samo throw; rzuci jeszcze raz TEN SAM wyjatek. Za to throw e rzuci chyba KOPIĘ? Z tym że na stackOv znalzazłem takie zdanie:

"Note that throw; is the only safe way to re-throw the current exception - it's not equivalent to
catch (Ex const & e) { throw e; }"

I nie rozumiem czemu to nie jest to samo co throw e; gdy e złapalismy przez referencje?
Jaka jest w takim razie roznica miedzy tymi 3 sytuacjami?

PS. ewentualnie sytuacja 4 byłaby taka:

try{
//cos tam
}catch(Ex const & e){
  throw e;
}
2

W przypadku bardziej skomplikowanych hierarchii dziedziczenia (gdy akceptujesz wyjątek innego typu niż ten otrzymany) widoczna jest różnica. Ponadto samo throw rzuca ponownie ten sam obiekt, a nie jego kopię.

struct foo_exception : std::runtime_error
{
    using std::runtime_error::runtime_error;
};

struct bar_exception : foo_exception
{
    using foo_exception::foo_exception;
};



int main()
{
    try {
        try {
            throw bar_exception{"!!!"};
        } catch (foo_exception const& e) {
            throw;
        }
    } catch(bar_exception const& e) {
        cout << "bar: " << e.what() << '\n';
    } catch(foo_exception const& e) {
        cout << "foo: " << e.what() << '\n';
    }

    try {
        try {
            throw bar_exception{"???"};
        } catch (foo_exception const& e) {
            throw e;
        }
    } catch(bar_exception const& e) {
        cout << "bar: " << e.what() << '\n';
    } catch(foo_exception const& e) {
        cout << "foo: " << e.what() << '\n';
    }
}

https://wandbox.org/permlink/z26huABoUQPTa0FB

1 użytkowników online, w tym zalogowanych: 0, gości: 1