简体   繁体   中英

do the default catch throw statements in C++ pass by value or reference

How does the default catch statement catch(...) {} catch an exception, by value or by reference?

Secondly, how does the default throw throw; throw an exception, by value or by reference?

The catch-all catch (...) doesn't give you access to the exception object at all, so the question is moot. [Corrected:] Rethrowing with throw; throws the original object. If the handler catches by value, then changes to the local copy do not affect the original, rethrown object. [/] See 15.3 (esp. clause 17) for details.

Check out some of the related questions on the right, like this one or this one and this one and this one .

You always catch what you have thrown. Let's say you have an exception class

 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) If you have thrown a pointer, you'll get the pointer:

Example 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 { } } 

Example 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) If you have thrown an object, you'll catch a reference to it:

Example 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"); } 

The following output is produced:

main BEGIN
f BEGIN
MyException::MyException() ctor
catch MyException: 1
MyException::~MyException() dtor
main END

Example 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 } } 

A throw copys the thrown value to an implementation defined location.
So the value is copied on throw (which means the type must be copyable).

When you catch you can choose to catch by value or reference.

catch(X  val) // Catch by value
{
}
catch(Y& val) // Catch by reference
{
}

The idiomatic why to catch is to catch by const reference. This is because if you catch by value there is a possibility of slicing when the exception is copied from its saved location to the catch value. If you catch by value the value is destroyed at the end of the catch block. The copy in the saved location is destroyed at the end of try/catch block where it was caught (and not re-thrown).

So when you catch with catch(...) nothing happens. The exception remains in unspecified location that the exception has already been copied into.

When you use throw to re-throw an exception. throw; . Again nothing happens as the exception is already in the unspecified location and nothing needs to happen.

Note: calling throw; when no exception is propagating is an error and will result in std::terminate being called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM