我应该使用哪一个?
catch (_com_error e)
或
catch (_com_error& e)
答案 0 :(得分:28)
第二个。这是我尝试引用Sutter
“按价值投掷,以参考方式捕捉”
正确学习
catch
:按值(而非指针)抛出异常 通过引用捕获它们(通常是const
)。这是组合 与异常语义最佳匹配。当重新抛出时 例外情况,只需throw;
至throw e;
。
这是完整的Item 73. Throw by value, catch by reference.
避免按值捕获异常的原因是它隐式地创建了异常的副本。如果异常属于子类,则有关它的信息将丢失。
try { throw MyException ("error") }
catch (Exception e) {
/* Implies: Exception e (MyException ("error")) */
/* e is an instance of Exception, but not MyException */
}
通过引用捕获可以避免此问题,方法是不复制异常。
try { throw MyException ("error") }
catch (Exception& e) {
/* Implies: Exception &e = MyException ("error"); */
/* e is an instance of MyException */
}
答案 1 :(得分:12)
就个人而言,我会选择第三种选择:
catch (const _com_error& e)
答案 2 :(得分:6)
另请注意,使用MFC时,您可能需要catch by pointer。否则,@ JaredPar的答案是你通常应该采用的方式(并且希望永远不必处理抛出指针的事情)。
答案 3 :(得分:3)
绝对是第二个。如果您有以下内容:
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
}
}
答案 4 :(得分:0)
在跟踪和扩展MS时,如果我期望返回HRESULT
的函数会产生很多COM异常,则可以这样做:
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);
}