我有一个像这样的功能:

bool op1();
bool op2();

bool foo() {
  CoInitialize(nullptr);
  if (!op1()) {
    CoUninitialize();
    return false;
  }
  // do more stuff, then call op2...
  if (!op2()) {
    CoUninitialize();
    return false;
  }
  // happy path
  CoUninitialize();
  return true;
}

我想重构foo()引发异常:
void foo() {
  CoInitialize(nullptr);
  if (!op1()) {
    CoUninitialize(); // I'm lazy, can't I automate this call?
    throw std::exception("Failed");
  }
  // ...

但是每次遇到错误时,我都必须调用CoUninitialize()

我考虑过将COM init调用包装在一个类中,因此析构函数will do the cleanup,但是拥有未使用的对象对我来说感觉很奇怪:
class comlib {
public:
  comlib() { CoInitialize(nullptr); }
  ~comlib() { CoUninitialize(); } // automated!
};

void foo() {
  comlib nobodyEverCallsMe;
  if (!op1()) {
    throw std::exception("Failed");
  }
  // ...

有更好的方法吗?

最佳答案

Raymond Chen已经using this method了一段时间,所以我确定可以,只要记住CoUninitialize CoInitialize,就只调用SUCCEEDED!

class CCoInitialize {
  HRESULT m_hr;
public:
  CCoInitialize() : m_hr(CoInitialize(NULL)) { }
  ~CCoInitialize() { if (SUCCEEDED(m_hr)) CoUninitialize(); }
  operator HRESULT() const { return m_hr; }
};


void Something()
{
  CCoInitialize init;
  ...
}

如果CoInitialize失败,有些人可能想抛出构造函数,但我认为这是不必要的,因为其他COM调用会失败。仅当您需要从CoInitialize捕获确切的HRESULT故障代码时,才执行此操作。

关于c++ - 使用CoInitialize和CoUninitialize引发C++异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47123650/

10-10 14:31