哪个是对的? catch(_com_error e)或catch(_com_error& e)?

时间:2008-09-29 23:07:56

标签: c++ exception com

我应该使用哪一个?

catch (_com_error e)  

catch (_com_error& e)

5 个答案:

答案 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);
}