实战c++中的智能指针unique_ptr系列-- 使用unique_ptr来避免if多层嵌套

时间:2021-02-14 19:44:29

博文引用连接:
http://www.jianshu.com/p/9898abc55677

今天看到这个文章,觉得没有很nice。

我们太喜欢流程控制了,在程序中写了太多的if else

也许我们对于逻辑非常的清晰,但是对于阅读你代码的人来说就是一场灾难。

很多人都说使用多态来避免过多的if else嵌套,但是有时候你会觉得新写一个类似乎有点小题大做,尤其在整个代码已经庞大的时候。

还有人说,可以把if else语句转换为switch语句,这样也可以适当的避免多层的if嵌套。

实战过程中,下面这个场景太熟悉不过了:
先创建一个对象A,然后再用这个对象去创建另外一个对象B。

    auto pa = CreateA();
status = doStuffByA(pa);
auto pb = CreateBbyA(pa);
status = doStuffByB(pb);

就像上面这段代码,正常的逻辑很简单,但是如果考虑到错误处理的话,代码就变得异常麻烦了。

下面这段代码单纯的依靠if-else处理问题,可以看到代码嵌套很严重,而且在很多地方都需要调用DestoryA(pa);,都是重复的逻辑。

bool Init(){
A* pa = nullptr;
B* pb = nullptr;
pa = CreateA();
if (pa) {
if (doStuffByA(pa)) {
pb = CreateBbyA(pa);
if (pb) {
if (doStuffByB(pb)) {
}
else {
DestoryB(pb);
DestoryA(pa);
return false;
}
}
else {
DestoryA(pa);
return false;
}
}
else {
DestoryA(pa);
return false;
}
}
else{
return false;
}
return true;
}

C++11下,我们有了利器unique_ptr

bool Init4()
{
auto deleterA = [&](A* p){ if (p) DestoryA(p); };
std::unique_ptr<A, decltype(deleterA)> pa(CreateA(),deleterA);

if (!pa){
return false;
}

if (doStuffByA(pa.get())){
return false;
}

auto deleterB = [&](B* p){ if (p) DestoryB(p); };
std::unique_ptr<B, decltype(deleterB)> pb(CreateBbyA(pa.get()), deleterB);

if (!pb){
return false;
}

if (doStuffByB(pb.get())){
return false;
}
pa.release();
pb.release();
return true;
}

上面的代码也是出自连接:http://www.jianshu.com/p/9898abc55677

有了前面的基础,读懂很容易吧:
pa pb均为具有自定义删除器的智能指针;
定义删除器用到了lambda表达式;
使用了unique_ptr的get()方法来 Returns the stored pointer.