如果我有一个 C++ 类 X,它实现了 COM 接口 IY 和 IZ,并且我有一个指向 X 类型对象的 IY 接口的指针 y,我这样做:
IZ *z = dynamic_cast<IZ *> ( y );
这不会影响对象的引用计数,是吗?我不必做一个 Release() 来解释它,对吧?
如果重要的话,我正在使用 ATL/COM。
我猜答案是“不,它不会增加引用计数,不,你不必 Release()”,但我想确定一下。
提前致谢。
如果我有一个 C++ 类 X,它实现了 COM 接口 IY 和 IZ,并且我有一个指向 X 类型对象的 IY 接口的指针 y,我这样做:
IZ *z = dynamic_cast<IZ *> ( y );
这不会影响对象的引用计数,是吗?我不必做一个 Release() 来解释它,对吧?
如果重要的话,我正在使用 ATL/COM。
我猜答案是“不,它不会增加引用计数,不,你不必 Release()”,但我想确定一下。
提前致谢。
不得出于多种原因使用 dynamic_cast:
而是使用 QueryInterface - 它会做你想要的。
即使您确定上述问题 - 投射不会改变 refcounter
当有人调用 IUnknown::AddRef() 时,COM 对象的引用计数会增加。QueryInterface(),根据 COM 规则,因为它给出一个新的接口指针,内部调用 AddRef()。
在您发布的代码中,您没有调用 AddRef(),也没有调用任何可能调用 AddRef() 的函数,那么为什么您认为引用计数会增加呢?
尽管 ATL/MFC 对人的大脑做了什么,但其中并没有魔法。如有疑问,您始终可以在 VS 中查看反汇编并逐步执行它并向自己证明AddRef() 没有被调用。
编辑:我想重申一下 Dewfy 所说的,不要这样做。使用查询接口()。或 CComQIPtr<> (如果你真的必须)。
进一步编辑:如果您使用 CComPtr<> 和 CComQIPtr<> 那么您不必调用 Release() 并且可以减轻找出正确引用计数的大部分负担。你真的应该考虑使用它们。
在 C++Builder 中,dynamic_cast
COM 接口指针实际上是QueryInterface
. 并且返回的指针,如果 QI 成功,得到AddRef
'd。
实现 COM 对象的类与更一般的 C++ 类具有不同的 vtable 布局,因此 C++ 样式dynamic_cast
无法工作;所以我认为这就是 C++Builder 做 QueryInterface 更明智的事情的原因。
(COM 的最初想法是将 C++ 对象模型推广为与语言无关的二进制标准;他们将 dynamic_cast 重命名为 QueryInterface)。
我想最好的答案是指 MSVC,如果 dynamic_cast 导致未定义的行为。