Do-While妙用

关于do-while,笔者之前一直停留在学习c++基础语法时的理解,然而后面读框架代码时经常看到do…while(0)这样的用法,当时不理解这样用的用意。
纸上得来终觉浅,绝知此事要躬行。 当我们看技术书籍或者看一些优秀的项目源码时,对于很多小地方可能也就是一目置之,自己亲身经历一次才会深刻的明白,这里也提醒自己以后多多注意细节。
最近在实现一个类的初始化函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
bool MapFactory::init()
{
bool ret = false;
ret = initSimple();
if(!ret){
return false;
}

ret = initMiddle();
if(!ret){
return false;
}

ret = initHard();
if(!ret){
return false;
}

ret = initSpecial();
if(!ret){
return false;
}

return ret;
}

当时笔者在写上面这段代码时就感觉好麻烦,好多的return语句。
然而,我们可以巧妙地借用下循环里break的思路,优化如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
bool MapFactory::init()
{
bool ret = false;
do{
ret = initSimple();
if(!ret){
//return false;
break;
}

ret = initMiddle();
if(!ret){
//return false;
break;
}

ret = initHard();
if(!ret){
//return false;
break;
}

ret = initSpecial();
if(!ret){
//return false;
break;
}
}while(0);

return ret;
}

当然上面的例子并没有恰当地表现出这个技巧的实用之处,因为上面的代码在每一次调用之时无外乎失败就直接返回,但是假如子初始化函数失败还需要释放资源,比如指针之类的。嗯,自行体会。

之前在阅读的代码中看到的do…while(0)代码更为常见的是红定义中,参加下面代码:

1
#define SAFE_DELETE(p) do{ delete p; p = NULL;} while(0)

假设这里去掉do…while(0),

1
#define SAFE_DELETE(p) delete p; p = NULL;

注意下面宏调用:

1
2
if(NULL != p) SAFE_DELETE(p)
else do something

这里如果是下面的定义方式,程序编译会报错,这里的do-while相当于提供了一种健壮的宏定义方式,至于个中细节,自行体会。
最后我想说的是,程序就像是一件艺术品,没有最好的代码实现, 只有更好,更优雅的代码。只有在一次又一次的实战中不断总结,才能不断提升自己。