【问题标题】:dynamic_cast of a COM object to a COM interface doesn't bump the reference count, does it?COM 对象到 COM 接口的 dynamic_cast 不会增加引用计数,是吗?
【发布时间】:2010-11-30 10:54:22
【问题描述】:

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

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

这不会增加对象的引用计数,是吗?我不必执行 Release() 来解释它,对吧?

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

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

提前致谢。

【问题讨论】:

    标签: interface com dynamic-cast reference-counting atlcom


    【解决方案1】:

    dynamic_cast 不得用于多种原因:

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

    改为使用 QueryInterface - 它会做你想做的事。

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

    【讨论】:

    • 是的,是的,又是。你甚至不知道实现是否真的是 C++。使用 QueryInterface() - 它与 dynamic_cast 非常接近,无论不同的互操作问题如何,它都能正常工作。
    【解决方案2】:

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

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

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2020-01-14
        • 2011-06-27
        • 1970-01-01
        • 2011-07-08
        • 2012-10-02
        • 2014-12-18
        • 2014-05-28
        • 2012-08-23
        • 2011-08-22
        相关资源
        最近更新 更多