1. 程式人生 > >實戰c++中的智慧指標unique_ptr系列-- 使用unique_ptr來避免if多層巢狀

實戰c++中的智慧指標unique_ptr系列-- 使用unique_ptr來避免if多層巢狀

今天看到這個文章,覺得沒有很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.