Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

catching std::exception by reference?

Tags:

c++

I have a silly question. I read this article about std::exception http://www.cplusplus.com/doc/tutorial/exceptions/

On catch (exception& e), it says:

We have placed a handler that catches exception objects by reference (notice the ampersand & after the type), therefore this catches also classes derived from exception, like our myex object of class myexception.

Does this mean that by using "&" you can also catch exception of the parent class? I thought & is predefined in std::exception because it's better to pass e (std::exception) as reference than object.

like image 566
user853069 Avatar asked Jul 20 '11 01:07

user853069


People also ask

Why is it preferred to catch exceptions by reference instead of by value?

An exception should be caught by reference rather than by value. The analyzer detected a potential error that has to do with catching an exception by value. It is much better and safer to catch exceptions by reference.

Why we have to catch a exception by reference explain?

To be more specific, if you caught std::exception by reference and you just simply use throw; , you will still rethrow the original SpecialException , while if you throw e , that SpecialException will be copied into std::exception so we lose information pretty much the same way as we lost information in the case of ...

How do you catch exceptions in C++?

Exception handling in C++ is done using three keywords: try , catch and throw . To catch exceptions, a portion of code is placed under exception inspection. This is done by enclosing this portion of code in a try block. When an exception occurs within the try block, control is transferred to the exception handler.

Should you always catch exceptions?

You should always list catched exceptions. They are predicted. If you want to catch unpredicted exceptions and handle them the same way, you should catch RuntimeException instead.


2 Answers

The reason for using & with exceptions is not so much polymorphism as avoiding slicing. If you were to not use &, C++ would attempt to copy the thrown exception into a newly created std::exception, potentially losing information in the process. Example:

#include <stdexcept> #include <iostream>  class my_exception : public std::exception {   virtual const char *what() const throw() {     return "Hello, world!";   } };  int main() {   try {     throw my_exception();   } catch (std::exception e) {     std::cout << e.what() << std::endl;   }   return 0; } 

This will print the default message for std::exception (in my case, St9exception) rather than Hello, world!, because the original exception object was lost by slicing. If we change that to an &:

#include <stdexcept> #include <iostream>  class my_exception : public std::exception {   virtual const char *what() const throw() {     return "Hello, world!";   } };  int main() {   try {     throw my_exception();   } catch (std::exception &e) {     std::cout << e.what() << std::endl;   }   return 0; } 

Now we do see Hello, world!.

like image 149
bdonlan Avatar answered Oct 02 '22 16:10

bdonlan


Does this mean that by using "&" you can also catch exception of the parent class?

No, this doesn't increase the scope of where you will catch exceptions from (e.g. from the parent class of the class that contains the try/catch code).

It also doesn't increase the types of exceptions that can be caught, compared to catching by value (catch(std::exception e) without the & - you'll still catch each exception that either is std::exception or derives from it).

What it increases is the amount of data that you will actually get when you catch the exception.

If an exception is thrown that derives from std::exception, and you catch it by value, then you are throwing out any extra behavior in that exception class. It breaks polymorphism on the exception class, because of Slicing.

An example:

class MyException : public std::exception { public:     virtual const char* what() const     {         return "hello, from my exception!";     } };  // ...  try {     throw MyException(); } catch(std::exception& e) {     // This will print "hello, from my exception!"     std::cout << e.what() << "\n"; }  // ...  try {     throw MyException(); } catch(std::exception e) {     // This will print "Unknown exception"     std::cout << e.what() << "\n"; } 
like image 27
Merlyn Morgan-Graham Avatar answered Oct 02 '22 16:10

Merlyn Morgan-Graham