IUnknown :: QueryInterface()是否会增加引用计数?

Meh*_*dad 7 com queryinterface iunknown

如果我有IUnknown *ptr,我需要调用Release()我获得的每个接口ptr->QueryInterface(),除了ptr->Release()在完成后调用ptr吗?

我曾经认为答案是肯定的,但MSDN引用的这句话让我很困惑:

有时,您可能需要获取对象的弱引用(也就是说,您可能希望获得指向其中一个接口的指针而不增加引用计数),但是通过调用QueryInterface后跟来执行此操作是不可接受的Release.

我不明白为什么这有问题 - 如果我调用ptr->QueryInterface()然后调用Release结果指针,对象上的引用计数是否仍然是正数?这是如何导致指针无效的?

ta.*_*.is 7

文档是正确的.并且您需要遵循引用计数规则 - 包括ReleaseQueryInterface创建对象之后调用从中获取的接口.

要清除为什么你不能做弱指针Release- 在调用中存在竞争条件QueryInterface,然后Release立即存在竞争条件.

  • Thread1创建对象 - 引用计数1
  • Thread2调用QueryInterface弱引用 - 引用计数2
  • Thread1释放对象 - 引用计数1
  • Thread2调用Release弱引用 - 引用计数0.对象被销毁.
  • Thread2尝试使用对象 - 错误.

警告是为了防止上述 - 可能是一些程序员认为他们可以"调用ptr->QueryInterface()然后调用Release结果指针"然后使用该对象......

  • 甚至没有线程,如果你在*weak*之前'释放'你的强*(让我们称之为)引用,那么*weak*引用不再有效.调用"释放"基本上是你说"好吧我已经完成"的方式 - 一旦你调用它,就停止使用该对象.如果你需要继续使用对象...不要调用`Release`. (2认同)
  • 这不仅仅是线程.如果您从QueryInterface调用获得的对象是COM撕下怎么办?在这种情况下,它的引用计数独立于主对象的引用计数(只要撕下遵循COM的对象标识规则,这是合法的).你对Release()的调用可能会导致释放撕掉,然后你会被留在指向释放内存的指针上. (2认同)

K-b*_*llo 5

IUnknown::QueryInterface 方法

检索指向对象上支持的接口的指针。

此方法在其返回的指针上调用 IUnknown::AddRef。

直接来自 IUnknown::QueryInterface 参考: http://msdn.microsoft.com/en-us/library/ms682521%28v=vs.85%29.aspx