为什么COM的IUnknown :: Release的这个实现工作?

从我见过的例子COM IUnknown::Release()函数的实现是这样的:

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

所以,如果m_count是0,所以我们删除“this”对象,并返回ref数。 我不明白的是为什么它有效?!?!

  1. 删除对象不会破坏调用堆栈,或者是因为它正在被线程所持有,所以它与对象无关。

  2. 如果这个对象被删除了,怎么可能返回m_count,它应该被删除。 我本来可以说服自己,如果删除代码之后会返回硬编码的0,那怎么回事呢?!?!

非常感谢你的帮助! 🙂

Solutions Collecting From Web of "为什么COM的IUnknown :: Release的这个实现工作?"

该代码是假的。 在递减之后永远不能信任m_count。 正确的代码总是这样的:

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

你观察到的是未定义的行为。 调用堆栈不会被delete this;delete this本身总是安全的,但呈现this指针无效 ,这意味着你不能取消它的了。

有两种可能的解释你所观察到的。 要么这个实现只是不引用this指针来获得m_count从函数返回时 – 它已经加载到一个寄存器,只是使用该值,所以this不是解除引用,你没有观察到任何问题或何时delete完成对象占用的内存仍映射到进程地址空间,并保持技术上的可访问性,因此解除引用成功, m_count被成功读取。 我想后者更可能。

无论什么解释是没有定义的行为,你不能依靠这个,用Remus Rusanu 在他的回答中提出的建议。