What object is rethrown in C++?

I am quite confused about the type of the object which is rethrown in C++. For example, in the code above, why is the output 241?

My understanding is that in Line 1, an object of class Bar is thrown. It is caught in Line 2. The object of type Bar is sliced to type of Foo.

However, when the exception is rethrown, what's the type of that? Why Line 3 is executed? It's not Foo any more?

What's the basic policy of rethrow? The type remains the same? Or anything changed?

#include <iostream>
using namespace std;

class Foo{
public:
    Foo(int i): i(i) {}
    Foo(){}
    int i;
};

class Bar: public Foo{
public:
    Bar(int i): Foo(i) {}
    Bar(const Bar& b){i=b.i;}

};

int main () {
    Bar b(1);
    try{
        try{ 
          throw b;                 //Line 1
        }
        catch(Foo& e){
            e.i=2;                     //Line 2  
            cout<<e.i;
            throw;
        }
        catch(Bar& e){
            e.i = 3;
            cout<<e.i;
            throw e;
        }
    }
    catch (Bar e) {
        e.i*=2;                   //Line 3
        cout<<e.i;
    }
    catch (Foo e) {
        e.i*=3;
        cout<<e.i;
    }

    cout<<b.i;
    return 0;
}

Answers


throw; on its own throws the same object. The object is really a Bar, even though your reference to it is a Foo&. So when you say, "It is caught in Line 2. The object of type Bar is sliced to type of Foo", that's not right. It's not sliced either by the catch or by the rethrow.

If you change the line throw; to throw e;, then it will be sliced, and you'll see 261. Also, when you catch by value the object is copied, and so potentially can be sliced.

The reason you get 1 at the end is that the object b is never thrown, and is not modified in any of the catch blocks. throw <expression>; throws a copy of its operand.


With throw; the exception currently being handled is propagated onwards, with no copying or slicing. (It doesn't matter what is in the parentheses here: catch (...) {throw;} will always rethrow the current exception, which is not necessarily the same as your e.)

If you changed it to throw e;, e may be copied and sliced to Foo.


Need Your Help

Not able to compile external precompiled shared library with Android-NDK

android eclipse android-ndk shared-libraries

I have two shared library: A.so and B.so and want to link them with my Android Project.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.