safe_delete(p)的若干心得

http://hi.baidu.com/hwrose/item/ffb488ca61c8ee090bd93aad

注:主要表现是safe_delete中的safe!

 

引言:safe_delete(p)这东西,最早是在DirectX里看到的。

     今天写程序的时候,在释放对象的时候下意识的用了assigned()。这是DELPHI的习惯,BCB里没有这个例程,我才恍然明白以前看到的safe_delete(p)的作用。

     不过事情到这还没完。由于年代久远,我对safe_delete(p)的写法不甚明了,于是BAIDU了一下,发现safe_delete(p)的写法竟然是这样的:

#define safe_delete(p) do{ delete p; p=NULL; } while(false) 

     这种写法的意义不是显而易见的,而且还有另外一种版本的safe_delete(),在此就不写了,同样的令人费解——或者说让初学C++编程的人费解。

     其实如此做的目的就是为了让程序更健壮。

     一般的想法是do ... while()中的条件是false,那么这个do ... while()完全可以省略啊。OK,我们假设把这里的do ... while()省略,来看看在实际编程中会发生什么情况。

     为了突出问题,我们只考虑这个语句块:

if (NULL!=p)
     safe_delete(p)
else
     ...

     编译器把宏解开后(注意,我们现在考虑没有do ... while()的情况 )

if (NULL!=p)
     delete p; p=NULL;
else
     ...

     很明显,这个else失去配对的if。就算不存在else子句,问题依然存在,我们的本意是如果p!=NULL的话,才释放对象,并将p悬挂起来;但是这里却变成了,不论p是否为NULL,它都会被置NULL。程序在这句并不是按照你的预想执行的,也就有潜在的危险。

     那我们把那两句话加上大括号行不行啊?我们还是尝试解开一下:

if (NULL!=p)
     safe_delete(p)
else
     ...

     编译器把宏解开后(注意,我们现在考虑没有do ... while()的情况 )

if (NULL!=p)
     { delete p; p=NULL; }
else
     ...

      这样看来就没问题了。不过对于safe_delete()来说,它更像一个语句,所以可以想象某个程序员写完safe_delete()之后随手加了一个分号,就成了“safe_delete(p);”这样else又失去配对了。对于这个问题,可以考虑将safe_delete()全大写,以暗示程序员这个为宏定义,但是人嘛,总有马虎大意的时候,为了排除能想出来的一切可能性,我们就加上了do ... while()这个另人费解的循环。我们再看一下展开的结果:

if (NULL!=p)
     do { delete p; p=NULL; } while(false)
else
     ...

     这样,对于之前提出的各种假设——else配对的问题;语句无条件被执行的问题;习惯性分号的问题,都可以杜绝。而且,对于这个do ... while()由于它是个假循环,不会影响效率(BCB6中会自动去掉这个循环)。它的意义完全在语意上。

     以上这些假设,都是建立在safe_delete()写在库中,因为库的作者并不知道库的使用者会怎么用这个宏,他所能做的只是尽可能的减少这个宏出错的可能性,让使用者放心的使用。

你可能感兴趣的:(safe_delete(p)的若干心得)