问题
Which one should I use?
catch (_com_error e)
or
catch (_com_error& e)
回答1:
The second. Here is my attempt at quoting Sutter
"Throw by value, catch by reference"
Learn to
catchproperly: Throw exceptions by value (not pointer) and catch them by reference (usually toconst). This is the combination that meshes best with exception semantics. When rethrowing the same exception, prefer justthrow;tothrow e;.
Here's the full Item 73. Throw by value, catch by reference.
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 */
}
回答2:
Personally, I would go for the third option:
catch (const _com_error& e)
回答3:
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).
回答4:
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
}
}
回答5:
Following and extending MS, I do it like that if I’m expecting a lot of COM exceptions from functions returning a HRESULT:
inline void TESTHR(HRESULT _hr){if FAILED(_hr) throw(_hr);}
//later:
try{
MSXML2::IXMLDOMDocumentPtr docPtr;
TESTHR(CoInitialize(NULL));
TESTHR(docPtr.CreateInstance("Msxml2.DOMDocument.6.0"));
// more
}catch (const _com_error& e){
CStringW out;
out.Format(L"Exception occurred. HR = %lx, error = %s", e.Error(), e.ErrorMessage());
MessageBoxW(NULL, out, L"Error", MB_OK);
}
来源:https://stackoverflow.com/questions/151124/which-is-correct-catch-com-error-e-or-catch-com-error-e