views:

1558

answers:

4

Which one should I use?

catch (_com_error e)

or

catch (_com_error& e)
+21  A: 

The second. Here is my attempt at quoting Sutter

"Throw by value, catch by reference"

Here's the full summary


The reason to avoid catching exceptions by value is that it implicitly makes a copy of the exception. If the exception is of a subclass, then information about it will be lost.

try { throw MyException ("error") } 
catch (Exception e) {
    /* Implies: Exception e (MyException ("error")) */
    /* e is an instance of Exception, but not MyException */
}

Catching by reference avoids this issue by not copying the exception.

try { throw MyException ("error") } 
catch (Exception& e) {
    /* Implies: Exception &e = MyException ("error"); */
    /* e is an instance of MyException */
}
JaredPar
do you mean the first?
Doug T.
Doug T: No the second. Catch by reference.
Martin York
A bit more detail in the answer would be nice. Leave link for the exact details but put in details (and example) about the most accepted method.
Martin York
I 2nd the point made by Martin York.
Richard Corden
Added some info and examples to the answer.
John Millikin
The exception is always copied. This is also important to note. Even if caught by reference. The difference is that you can downcast the reference to the subtype, while catch by value always slices the object.
QBziZ
Also, as stated in "C++ Coding Standards", you should use throw; to re-throw the execption if needed, not throw e; because the polymorphism is always preserved by throw; (but this is only useful if you catch by reference)
Miquella
+3  A: 

Definitely the second. If you had the following:

class my_exception : public exception
{
  int my_exception_data;
};

void foo()
{
  throw my_exception;
}

void bar()
{
  try
  {
    foo();
  }
  catch (exception e)
  {
    // e is "sliced off" - you lose the "my_exception-ness" of the exception object
  }
}
1800 INFORMATION
I believe the point of the question was whether to catch by reference or by value, not whether to catch some base class version of the exception.
Matt Dillard
The slicing problem is one of the main reasons you should always catch by reference
1800 INFORMATION
I see now what you mean - if e were caught by reference in your example, polymorphism would kick in appropriately.
Matt Dillard
Scott Meyers goes into great detail on this topic in Effective C++
1800 INFORMATION
+5  A: 

Also, note that, when using MFC, you may have to catch by pointer. Otherwise, @JaredPar's answer is the way you should normally go (and hopefully never have to deal with things that throw a pointer).

Kris Kumler
+6  A: 

Personally, I would go for the third option:

catch (const _com_error& e)
jonner
Yes, if at all possible, it should be const.
Miquella