2011-01-06 60 views
7

我有一些關於懶惰評估C++的問題,我可以確定代碼的這個片段總是可以工作,或者它是個壞主意嗎?如果是,爲什麼?由於事先在C++中的好習慣(懶惰評估)

如果(currentNode == 0 || * currentNode == 元件){ 回報; }

+0

它會一直工作,但它可能仍然是一個壞主意。 :)需要更多的上下文來評估代碼。 – 2011-01-06 09:44:13

+0

@Karl:你覺得怎麼樣都不好。 – 2011-01-06 09:47:47

+0

它**可能是壞的,*取決於上下文*,currentNode是一個指針,或者它被允許爲空,或者邏輯以這種方式工作,或者... – 2011-01-06 09:48:58

回答

19

保證工作:邏輯AND和OR表達式鏈從左到右計算,如果第一個子表達式滿足條件,則不計算其他子表達式。

在你的情況下,如果currentNode爲空,它將永遠不會被第二個子表達式取消引用,所以代碼是安全的。

由於@jdv指出的是,這個被稱爲短路評價,不懶評價。後者是一種編程技術,您可以透明地向客戶端計算所需值,僅在具體需要時才第一次計算所需值。一個簡單的例子:

class Example { 
    SomeClass *theObject = null; 
public: 
    SomeClass *getTheObject() { 
    if (!theObject) { 
     theObject = doResourceConsumingCalculation(); 
    } 
    return theObject; 
    } 
}; 

注意的Example的客戶端不知道的實現細節theObject是懶洋洋地評估的,所以你可以自由更換來回急切和懶惰的評價之間,而不影響的公共接口類。

(當然,在實際生產代碼,getTheObject應在一個單獨的cpp文件中實現,並且它也許應該包括同步,錯誤處理碼等,這僅僅是:-)

11

是的,這是安全的。它被稱爲短路布爾評估。

對於完整性,值得一提的是,原則上可以覆蓋||。和& &運營商。如果這樣做,這將打破短路評估,因此不被推薦。

3

對於懶惰一個簡單的例子 - 在多線程環境中評估您應該考慮使用boost :: once來執行一次性加載。

class Example 
{ 
    mutable boost::once_flag flag; 
    mutable SomeClass * theObject; 

    void loadTheObject() const; 

public: 
    Example() : 
     flag(BOOST_ONCE_INIT), 
     theObject(NULL) 
    { 
    } 

    SomeClass * getTheObject() const 
    { 
     boost::call_once(flag, boost::bind(&Example::loadTheObject, this)); 
     return theObject; 
    } 
};