2011-01-06 14 views
7

Ich habe eine Frage über die faule Bewertung von C++, kann ich sicher sein, dass dieser Code-Schnipsel immer funktioniert, oder es ist eine schlechte Idee? wenn ja, warum? Dank im Vorausgute Praxis in C++ (faule Bewertung)

if (currentNode == 0 || * currentNode == Element) { return; }

+0

Es wird immer funktionieren, aber es könnte immer noch eine schlechte Idee sein. :) Mehr Kontext ist erforderlich, um den Code zu bewerten. –

+0

@Karl: Was denkst du ist schlecht daran? –

+0

Es ** könnte ** schlecht sein, * abhängig vom Kontext *, dass "currentNode" an erster Stelle ein Zeiger ist oder dass es Null sein darf, oder dass die Logik auf diese Weise funktioniert, oder ... –

Antwort

19

Es funktioniert garantiert: logische UND- und OR-Ausdrucksketten werden von links nach rechts ausgewertet, und wenn der erste Teilausdruck die Bedingung erfüllt, werden keine weiteren Teilausdrücke ausgewertet.

In Ihrem Fall, wenn currentNode Null ist, wird es nie durch den zweiten Teilausdruck dereferenziert, so dass der Code sicher ist.

Wie @jdv obwohl darauf hingewiesen wird diese Kurzauswertung genannt, nicht lazy evaluation. Bei letzterem handelt es sich um eine Programmiertechnik, bei der Sie für den Kunden den erforderlichen Wert nur beim ersten Mal berechnen, wenn er konkret benötigt wird. Ein einfaches Beispiel:

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

Beachten Sie, dass der Kunde von Example der Umsetzung Details nicht bewusst ist, dass theObject lazily ausgewertet, so dass Sie frei hin und her zwischen eifrig und faul Auswertung zu ändern, ohne die öffentliche Schnittstelle des zu beeinflussen Klasse.

(Natürlich in realen Produktionscode sollten getTheObject in einer separaten CPP-Datei implementiert werden, und es sollte wahrscheinlich auch die Synchronisation, Fehlerbehandlung Code usw. Dies ist nur ein einfaches Beispiel :-)

+0

sub * h * Ausdruck – marcog

+0

@marcog, danke, behoben :-) –

11

Ja, das ist sicher. Dies wird als boolesche Kurzschlussauswertung bezeichnet.

Für Compleynes ist zu erwähnen, dass es prinzipiell möglich ist, das || zu überschreiben und & & Operatoren. Wenn Sie dies tun, wird dies die Kurzschlussauswertung unterbrechen und wird daher nicht empfohlen.

+0

+1 für die Klärung der Terminologie :-) –

3

Für faul In einer Multithreading-Umgebung sollten Sie Boost :: einmal in Betracht ziehen, um das einmalige Laden durchzuführen.

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

Hinweis: Es gibt jetzt ein "einmal" Konstrukt in Standard C++. Wenn die Möglichkeit besteht, dass der Wert nicht geladen wird, ist es besser, dass die geladene Methode keine Ausnahme "leckt". Es ist daher eine gute Idee, eine Art Dekorator in Ihrem Cache zu haben, der den fehlgeschlagenen Zustand anzeigt. – CashCow