Что правильно? catch (_com_error e) или catch (_com_error & e)?

Какой я должен использовать?

catch (_com_error e)  

или

catch (_com_error& e)

Ответ 1

Второй. Вот моя попытка процитировать Sutter

"Бросить по значению, выхватить по ссылке"

Научитесь catch правильно: выбросите исключения по значению (не указателю) и поймать их по ссылке (обычно до const). Это комбинация который лучше всего связывает с семантикой исключения. При повторном исключение, предпочитайте только throw; - throw e;.

Здесь полный Пункт 73. Бросок по значению, 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 */
}

Ответ 2

Лично я бы выбрал третий вариант:

catch (const _com_error& e)

Ответ 3

Также обратите внимание, что при использовании MFC вам может потребоваться catch by pointer. В противном случае, ответ @JaredPar - это то, как вы обычно должны идти (и, надеюсь, никогда не придется иметь дело с вещами, которые бросают указатель).

Ответ 4

Определенно второе. Если у вас есть следующее:

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

Следуя и расширяя MS, я делаю это так, если я ожидаю много COM-исключений из функций, возвращающих 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);
}