2011-01-06 18 views
7

मुझे सी ++ के आलसी मूल्यांकन के बारे में कुछ सवाल है, क्या मुझे यकीन है कि कोड का यह स्निपेट हमेशा काम करेगा, या यह बुरा विचार है? यदि हां, क्यों? अग्रिम धन्यवादसी ++ (आलसी मूल्यांकन) में अच्छा अभ्यास

अगर (currentNode == 0 || * currentNode == तत्व) { वापसी; }

+0

यह हमेशा काम करेगा, लेकिन यह अभी भी एक बुरा विचार हो सकता है। :) कोड का मूल्यांकन करने के लिए अधिक संदर्भ की आवश्यकता है। –

+0

@ करल: आपको इसके बारे में क्या बुरा लगता है। –

+0

यह ** खराब हो सकता है, * संदर्भ * के आधार पर, कि 'currentNode' पहले स्थान पर एक सूचक है, या यह शून्य होने की अनुमति है, या तर्क इस तरह से काम करता है, या ... –

उत्तर

19

यह काम करने की गारंटी है: तार्किक और और अभिव्यक्ति श्रृंखलाओं का मूल्यांकन बाएं से दाएं से किया जाता है, और यदि पहला उप-संपीड़न स्थिति को पूरा करता है, तो कोई और सबएक्सप्रेस का मूल्यांकन नहीं किया जाता है।

अपने मामले में, यदि currentNode शून्य है, तो इसे दूसरे उप-संपीड़न द्वारा कभी भी संदर्भित नहीं किया जाएगा, इसलिए कोड सुरक्षित है।

रूप @jdv हालांकि कहे अनुसार, इस कहा जाता है शॉर्ट सर्किट मूल्यांकन, नहीं आलसी मूल्यांकन। उत्तरार्द्ध एक प्रोग्रामिंग तकनीक है जहां आप क्लाइंट के लिए पारदर्शी रूप से, केवल आवश्यक समय की गणना करते हैं जब इसे ठोस रूप से जरूरी होता है। एक साधारण उदाहरण:

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

ध्यान दें कि Example की ग्राहक कार्यान्वयन विस्तार है कि theObject lazily मूल्यांकन किया जाता है के बारे में पता है, तो आप की सार्वजनिक इंटरफ़ेस को प्रभावित किए बिना आगे और पीछे उत्सुक और आलसी मूल्यांकन के बीच परिवर्तित करने के लिए स्वतंत्र हैं कक्षा।

(बेशक, वास्तविक उत्पादन कोड में, getTheObject एक अलग cpp फ़ाइल में लागू किया जाना चाहिए, और यह शायद तुल्यकालन, त्रुटि हैंडलिंग कोड आदि को शामिल करना चाहिए यह सिर्फ एक साधारण उदाहरण :-)

+0

उप * एच * अभिव्यक्ति – marcog

+0

@marcog, धन्यवाद, तय :-) –

11

हाँ यह सुरक्षित है। इसे शॉर्ट-सर्किट बूलियन मूल्यांकन कहा जाता है।

पूर्णता के लिए यह उल्लेखनीय है कि सिद्धांत रूप में यह ओवरराइड करना संभव है || और & & ऑपरेटरों। यदि आप ऐसा करते हैं, तो यह शॉर्ट सर्किट मूल्यांकन तोड़ देगा, और इसलिए इसे पूरा नहीं किया जाता है।

+0

स्पष्टीकरण शब्दावली के लिए +1 :-) –

3

आलसी के लिए है - बहु-थ्रेडेड वातावरण में मूल्यांकन, आपको एक बार लोडिंग करने के लिए बूस्ट :: एक बार उपयोग करने पर विचार करना चाहिए।

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

नोट: मानक सी ++ में अब "एक बार" निर्माण होता है। यदि कोई संभावना है कि मान लोड नहीं होगा, तो यह बेहतर होगा कि लोड होने वाली विधि अपवाद को "रिसाव" न करे। इसलिए यह एक अच्छा विचार है कि आपके कैश में किसी प्रकार का सजावट हो जो असफल स्थिति दिखाता है। – CashCow

संबंधित मुद्दे