我們太喜歡流程控制了,在程序中寫了太多的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 pa(CreateA(),deleterA);
if (!pa){
return false;
}
if (doStuffByA(pa.get())){
return false;
}
auto deleterB = [&](B* p){ if (p) DestoryB(p); };
std::unique_ptr pb(CreateBbyA(pa.get()), deleterB);
if (!pb){
return false;
}
if (doStuffByB(pb.get())){
return false;
}
pa.release();
pb.release();
return true;
}
有了前面的基礎,讀懂很容易吧:
pa pb均為具有自定義刪除器的智能指針;
定義刪除器用到了lambda表達式;
使用了unique_ptr的get()方法來 Returns the stored pointer.