WEB开发网
开发学院软件开发VC 用ATL建立轻量级的COM对象(2) 阅读

用ATL建立轻量级的COM对象(2)

 2006-07-21 11:44:36 来源:WEB开发网   
核心提示: 许多开发人员将智能指针看成是对过于的复杂编程任务的简化,我最初也是这么认为的,用ATL建立轻量级的COM对象(2)(6),但只要留意它们使用COM智能指针的方法,就会逐渐认识到它们引入的潜在危险与它们解决的问题一样多,国内目前还没有这本书的中译本或影印本,有关COM智能指针的更多特定信息,

许多开发人员将智能指针看成是对过于的复杂编程任务的简化。我最初也是这么认为的。但只要留意它们使用COM智能指针的方法。就会逐渐认识到它们引入的潜在危险与它们解决的问题一样多。

关于这一点,我用一个现成的使用原始指针的函数为例:

void f(void) {
  IFoo *pFoo = 0;
  HRESULT hr = GetSomeObject(&pFoo);
  if (SUCCEEDED(hr)) {
   UseSomeObject(pFoo);
   pFoo->Release();
  }
}
将它自然而然转换到使用CComPtr。

void f(void) {
  CComPtr<IFoo> pFoo = 0;
  HRESULT hr = GetSomeObject(&pFoo);
  if (SUCCEEDED(hr)) {
   UseSomeObject(pFoo);
   pFoo->Release();
  }
}
  注意CComPtr 和 CComQIPtr输出所有受控接口成员,包括AddRef和Release。可惜当客户端通过操作符->的结果调用Release时,智能指针很健忘 ,会二次调用构造函数中的Release。显然这是错误的,编译器和链接器也欣然接受了这个代码。如果你运气好的话,调试器会很快捕获到这个错误。

使用ATL智能指针的另一个要引起注意的风险是类型强制转换操作符对原始指针提供的访问。如果隐式强制转换操作符的使用存在争议。当 ANSI/ISO C++ 委员会在决定采用某个C++串类时,他们明确禁止隐式类型转换。而是要求必须显式使用c_str函数在需要常量char *(const char *)的地方传递标准C++串。ATL提供了一种隐含式的类型转换操作符顺利地解决了这个问题。通常,这个转换操作符可以根据你的喜好来使用,允许你将智能指针传递到需要用原始指针的函数。

void f(IUnknown *pUnk) {
  CComPtr unk = pUnk;
  // 隐式调用操作符IUnknown *()
  CoLockObjectExternal(unk, TRUE, TRUE);
}
这段代码能正确运行,但是下面的代码也不会产生警告信息,编译正常通过: HRESULT CFoo::Clone(IUnknown **ppUnk) {
  CComPtr unk;
  CoCreateInstance(CLSID_Foo, 0, CLSCTX_ALL,
  IID_IUnknown, (void **) &unk);
  // 隐式调用操作符IUnknown *()
  *ppUnk = unk;
  return S_OK;
}
  在这种情况下,智能指针(unk)对原始值针**ppUnk的赋值触发了与前面代码段相同的强制类型转换。在第一个例子中,不需要用AddRef。在第二个例子中,必须要用AddRef。

有关使用智能指针的更详细一般信息,请参见Scott Meyer的《More Effective C++》(Addison-Wesley, 1995年出版)。国内目前还没有这本书的中译本或影印本。有关COM智能指针的更多特定信息,请参见Don Box的一篇关于智能指针的专题文章http://www.develop.com/dbox/cxx/SmartPointer.htm。 (待续)

上一页  1 2 3 4 5 6 

Tags:ATL 建立 轻量级

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接