2011-01-06 15 views
7

私はC++の怠惰な評価についていくつかの質問がありますが、コードのこのスニペットが常に機能するか、それとも悪い考えですか?はい、なぜですか?予めC++(怠惰な評価)の良い練習

のおかげで(現ノード== 0 || *現ノード== 素子){ 戻った場合、 }

+0

いつもうまくいくが、それでもやはり悪い考えかもしれない。 :)コードを評価するために、より多くのコンテキストが必要です。 –

+0

@Karl:あなたはそれについて悪いと思いますか? –

+0

** **コンテキスト*によっては、 'currentNode'が最初のポインタであるか、ヌルであることが許されているか、またはロジックがこのように動作するか、または... –

答えて

19

正常に動作することが保証されています。論理ANDおよびOR式チェーンは左から右へ評価され、最初の部分式が条件を満たす場合、それ以上の部分式は評価されません。

currentNodeがnullの場合は、2番目の部分式で逆参照されることはありませんので、コードは安全です。

@jdvがが指摘したように、これは短絡評価、ない遅延評価と呼ばれています。後者は、クライアントに透過的に、具体的に必要なときに初めて必要な値を計算するプログラミング手法です。単純な例:ExampleのクライアントがtheObjectが遅延評価されていることを実装の詳細を知らないので、あなたがパブリックインターフェイスに影響を与えることなく、前後に熱心と遅延評価の間に変更することが自由であることを

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

注意クラス。

(もちろん、実際の生産コードでは、getTheObjectは別々のcppファイルに実装されなければならない、そしてそれはおそらくこれは怠惰のために

+0

サブ* h *式 – marcog

+0

@marcog、ありがとう、固定:-) –

11

はいこれは安全です。これは短絡ブール評価と呼ばれます。

完了については、原則として、||オペレータは& &です。そうすると、短絡回路の評価が中断されますので、推奨されません。

+0

+1用語の明確化のため: –

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; 
    } 
}; 
+0

注:標準C++には "once"構造が追加されました。 値がロードされない可能性がある場合は、ロードするメソッドが例外を「リーク」しない方が良いです。したがって、失敗した状態を示す何らかの種類のデコレータをキャッシュに格納することをお勧めします。 – CashCow

関連する問題