實戰c++中的智慧指標unique_ptr系列-- 使用unique_ptr來避免if多層巢狀
阿新 • • 發佈:2019-02-03
今天看到這個文章,覺得沒有很nice。
我們太喜歡流程控制了,在程式中寫了太多的if else
也許我們對於邏輯非常的清晰,但是對於閱讀你程式碼的人來說就是一場災難。
很多人都說使用多型來避免過多的if else巢狀,但是有時候你會覺得新寫一個類似乎有點小題大做,尤其在整個程式碼已經龐大的時候。
還有人說,可以把if else語句轉換為switch語句,這樣也可以適當的避免多層的if巢狀。
實戰過程中,下面這個場景太熟悉不過了:
先建立一個物件A,然後再用這個物件去建立另外一個物件B。
auto pa = CreateA();
status = doStuffByA(pa);
auto pb = CreateBbyA(pa);
status = do StuffByB(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;
}
有了前面的基礎,讀懂很容易吧:
pa pb均為具有自定義刪除器的智慧指標;
定義刪除器用到了lambda表示式;
使用了unique_ptr的get()方法來 Returns the stored pointer.