2011-01-06 3 views
7

C++의 게으른 평가에 대한 질문이 있습니다.이 코드 스 니펫이 항상 작동하는지 또는 나쁜 생각인지 확신 할 수 있습니까? 그렇다면 왜? 미리 감사C++ (lazy evaluation)의 우수 사례

경우 (currentNode == 0 || * currentNode의 == 소자) { 창; }

+0

항상 작동하지만 여전히 좋지 않은 아이디어 일 수 있습니다. :) 코드를 평가하기 위해서는 더 많은 컨텍스트가 필요합니다. –

+0

@ 칼 : 너 그것에 대해 나쁘다고 생각하니? –

+0

** ** 컨텍스트 *에 따라 ** currentNode가 첫 번째 위치의 포인터이거나 null이 될 수 있거나 논리가이 방법으로 작동한다는 사실이 * 좋지 않을 수도 있습니다. –

답변

19

작동이 보장됩니다. 논리적 AND 및 OR 표현식 체인은 왼쪽에서 오른쪽으로 평가되며 첫 번째 하위 표현식이 조건을 충족하면 더 이상 하위 표현식이 평가되지 않습니다.

currentNode이 null이면 두 번째 하위 표현식에 의해 참조 해제되지 않으므로 코드가 안전합니다. @jdv 그래도 지적

,이 단락 회로 평가하지 게으른 평가이라고합니다. 후자는 클라이언트에게 투명하게 사용자가 구체적으로 필요할 때만 처음으로 필요한 값을 계산하는 프로그래밍 기법입니다. 가장 단순한 예 : Example의 클라이언트가 theObject가 게으르게 평가되는 구현의 세부 사항을 인식하지 못하는, 그래서 당신의 공용 인터페이스에 영향을주지 않고 앞뒤로 열망과 게으른 평가 사이에 자유롭게 변경할 수 있음을

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

주 수업.

는 (물론, 실제 생산 코드에서 getTheObject은 별도의 cpp 파일에 구현되어야하고, 아마 이것은 게으른 들어

+0

sub * h * expression – marcog

+0

@marcog, 고마워, 고정 :-) –

11

예. 안전합니다. 이를 단락 부울 평가라고합니다.

completes의 경우 원칙적으로 || 및 & & 연산자. 그렇게하면 단락 회로 평가가 중단되므로 권장하지 않습니다.

+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