为什么COM IUnknown :: Release的实现有效?

时间:2011-02-01 18:27:40

标签: c++ windows com

从示例中我看到COM IUnknown::Release()函数实现是这样的:

ULONG Release()
{
    InterlockedDecrement(&m_count);
    if(m_count == 0) {
       delete this;
    }
    return m_count;
}

因此,如果m_count为0,那么我们将删除“this”对象,并返回引用计数。 我不明白为什么它有效?!?!

  1. 删除对象不会破坏调用堆栈,也可以,因为它是由线程保留的,所以它与对象无关???

  2. 如果对象已被删除,我们怎么可能返回m_count,它应该被删除。我本可以说服自己没关系,如果删除后代码会返回硬编码0,但为什么它会返回会员?!?!

  3. 非常感谢你的帮助! : - )

2 个答案:

答案 0 :(得分:15)

那段代码是虚假的。在减少之后,人们永远不能相信m_count 。正确的代码总是,如下所示:

ULONG Release()
{
     ULONG count = InterlockedDecrement(&m_count);
     if(count == 0){ delete this; }
     return count;
}

答案 1 :(得分:1)

您观察到的是未定义的行为。调用堆栈不会被delete this;delete this by itself is always safe更改,而是renders this pointer invalid,这意味着您无法再取消引用它。

对你观察到的内容有两种可能的解释。有问题的实现只是在从函数返回时没有取消引用this指针以获取m_count - 它将它加载到寄存器中并且只使用该值,因此this不是取消引用并且您没有发现任何问题,或者当delete完成时,对象占用的内存仍然映射到进程地址空间并且在技术上仍然可访问,因此取消引用this成功并m_count已成功读取。我想后者更有可能。

无论未解释的行为是什么解释,您都不能依赖它,使用user Remus Rusanu建议的in his answer