2

如果我有一个 C++ 类 X,它实现了 COM 接口 IY 和 IZ,并且我有一个指向 X 类型对象的 IY 接口的指针 y,我这样做:

IZ *z = dynamic_cast<IZ *> ( y );

这不会影响对象的引用计数,是吗?我不必做一个 Release() 来解释它,对吧?

如果重要的话,我正在使用 ATL/COM。

我猜答案是“不,它不会增加引用计数,不,你不必 Release()”,但我想确定一下。

提前致谢。

4

3 回答 3

4

不得出于多种原因使用 dynamic_cast:

  • 你不知道destination是否支持RTTI
  • 您不确定 OLE 是否不会为您创建代理
  • ...

而是使用 QueryInterface - 它会做你想要的。

即使您确定上述问题 - 投射不会改变 refcounter

于 2009-09-22T15:39:16.360 回答
3

当有人调用 IUnknown::AddRef() 时,COM 对象的引用计数会增加。QueryInterface(),根据 COM 规则,因为它给出一个新的接口指针,内部调用 AddRef()。

在您发布的代码中,您没有调用 AddRef(),也没有调用任何可能调用 AddRef() 的函数,那么为什么您认为引用计数会增加呢?

尽管 ATL/MFC 对人的大脑做了什么,但其中并没有魔法。如有疑问,您始终可以在 VS 中查看反汇编并逐步执行它并向自己证明AddRef() 没有被调用。

编辑:我想重申一下 Dewfy 所说的,不要这样做。使用查询接口()。或 CComQIPtr<> (如果你真的必须)。

进一步编辑:如果您使用 CComPtr<> 和 CComQIPtr<> 那么您不必调用 Release() 并且可以减轻找出正确引用计数的大部分负担。你真的应该考虑使用它们。

于 2009-09-22T15:53:25.200 回答
0

在 C++Builder 中,dynamic_castCOM 接口指针实际上是QueryInterface. 并且返回的指针,如果 QI 成功,得到AddRef'd。

实现 COM 对象的类与更一般的 C++ 类具有不同的 vtable 布局,因此 C++ 样式dynamic_cast无法工作;所以我认为这就是 C++Builder 做 QueryInterface 更明智的事情的原因。

(COM 的最初想法是将 C++ 对象模型推广为与语言无关的二进制标准;他们将 dynamic_cast 重命名为 QueryInterface)。

我想最好的答案是指 MSVC,如果 dynamic_cast 导致未定义的行为。

于 2014-08-19T10:41:33.390 回答