释放前的临时指针?
Temporary pointer before releasing?
我查看了 atlbase.h
以了解 CComPtr<>
是如何实现的,并偶然发现了基础 class CComPtrBase<>
中的 Release()
函数像这样释放底层对象:
// Release the interface and set to NULL
void Release() throw()
{
T* pTemp = p;
if (pTemp)
{
p = NULL;
pTemp->Release();
}
}
我的智力不够好,看不出这个临时指针有什么意义pTemp
?
为什么这段代码不只是:
void Release() throw()
{
if (p)
{
p->Release();
// EDIT:
p = NULL;
}
}
现在如果你看一下析构函数,析构函数的定义就像我对上面示例的期望,有什么区别?
这里有两种可能的解释:
- 如果
p->Release()
抛出,那么在第二个变体中它不会被设置为 NULL
,而在第一个变体中它会被设置为 NULL
。请注意,封闭函数已声明为 throw()
,因此它不应抛出异常。此函数可能是在添加 throw()
说明符之前编写的。 (或者也许编码器习惯于在这种情况下进行防御性编码并使用通用模式。)
- 第一个变体可以进行尾调用优化,而第二个则不能。
我查看了 atlbase.h
以了解 CComPtr<>
是如何实现的,并偶然发现了基础 class CComPtrBase<>
中的 Release()
函数像这样释放底层对象:
// Release the interface and set to NULL
void Release() throw()
{
T* pTemp = p;
if (pTemp)
{
p = NULL;
pTemp->Release();
}
}
我的智力不够好,看不出这个临时指针有什么意义pTemp
?
为什么这段代码不只是:
void Release() throw()
{
if (p)
{
p->Release();
// EDIT:
p = NULL;
}
}
现在如果你看一下析构函数,析构函数的定义就像我对上面示例的期望,有什么区别?
这里有两种可能的解释:
- 如果
p->Release()
抛出,那么在第二个变体中它不会被设置为NULL
,而在第一个变体中它会被设置为NULL
。请注意,封闭函数已声明为throw()
,因此它不应抛出异常。此函数可能是在添加throw()
说明符之前编写的。 (或者也许编码器习惯于在这种情况下进行防御性编码并使用通用模式。) - 第一个变体可以进行尾调用优化,而第二个则不能。