2008-09-25 3 views
15

सी में में एक चर आरंभ किया जा रहा ++ आप एक चर एक में है, इसलिए की तरह प्रारंभ कर सकते हैं अगर बयान:प्रो/चोर: एक सशर्त बयान

if (CThing* pThing = GetThing()) 
{ 
} 

एक यह बुरा या अच्छा शैली क्यों पर विचार करेंगे? लाभ और नुकसान क्या हैं?

व्यक्तिगत रूप से मुझे इस शैली को पसंद है क्योंकि यह पीटीएचंग चर के दायरे को सीमित करता है, इसलिए जब यह नल होता है तो इसे गलती से कभी भी इस्तेमाल नहीं किया जा सकता है। हालांकि, मुझे यह पसंद नहीं है कि आप यह नहीं कर सकते:

if (CThing* pThing = GetThing() && pThing->IsReallySomeThing()) 
{ 
} 

यदि उपर्युक्त काम करने का कोई तरीका है, तो कृपया पोस्ट करें। लेकिन अगर यह अभी संभव नहीं है, तो भी मैं जानना चाहूंगा कि क्यों।

Question borrowed from here, similar topic but PHP.

उत्तर

18

महत्वपूर्ण बात यह है कि सी ++ में एक घोषणा अभिव्यक्ति नहीं है।

bool a = (CThing* pThing = GetThing()); // not legit!! 

आप एक अगर दोनों में एक घोषणा और बूलियन तर्क नहीं कर सकते बयान, सी ++ भाषा कल्पना खास तौर से किसी एक अभिव्यक्ति या एक घोषणा अनुमति देता है।

if(A *a = new A) 
{ 
    // this is legit and a is scoped here 
} 

हम कैसे जान सकते हैं कि अभिव्यक्ति में एक शब्द और दूसरे के बीच परिभाषित किया गया है या नहीं?

if((A *a = new A) && a->test()) 
{ 
    // was a really declared before a->test? 
} 

बुलेट काटने और आंतरिक का उपयोग करें। गुंजाइश नियम उपयोगी होते हैं और अपने तर्क स्पष्ट है:

if (CThing* pThing = GetThing()) 
{ 
    if(pThing->IsReallySomeThing()) 
    { 
    } 
} 
+1

"(ए * ए = नया ए) और एक-> परीक्षण()" यह मानक सी ++ नहीं है। (-1) –

+0

मैं तकनीकी उत्तरदायित्व के लिए यह उत्तर स्वीकार करूंगा। जिस बारे में चर्चा बेहतर है वह वास्तव में अत्यधिक व्यक्तिपरक है, मैं अपनी शुरुआती पोस्ट से शैली पसंद करता हूं, लेकिन मेरा टीडी नहीं चाहता कि मैं इसका इस्तेमाल करूं, इसलिए मैं नहीं करता हूं। समझौता के रूप में दायरे को सीमित करने के लिए मैं हमेशा अतिरिक्त ब्रैकेट का उपयोग कर सकता हूं। – steffenj

2

यह में सी ++ के बाद से काम नहीं करता है चाहिए भले ही यह short circuiting evaluation का समर्थन करता है।

if ((CThing* pThing = GetThing()) && (pThing->IsReallySomeThing())) 
{ 
} 

अं .. एक सशर्त में से एक मिस '=' आम बग की वजह से देख Wesley Tarle's answer

+0

मैं कोशिश करूंगा ... मुझे याद है कि मैंने सभी प्रकार के ब्रैकेट प्लेसमेंट की कोशिश की लेकिन कोई भी काम नहीं करेगा, हालांकि कंपाइलर त्रुटियों को ब्रैकेट के आधार पर बहुत कुछ बदल गया है। – steffenj

+0

"लघु सर्किट मूल्यांकन" ... मैं इसे अभी तक "प्रारंभिक" के रूप में जानता हूं। यह मेरे लिए नया है। – steffenj

2

एक कारण यह है कि मैं सामान्य रूप से नहीं करते है: शायद निम्नलिखित की कोशिश मत करो परीक्षा। मैं उन लोगों को पकड़ने के लिए सेट त्रुटि/चेतावनियों के साथ लिंट का उपयोग करता हूं। फिर यह सशर्त के अंदर सभी असाइनमेंट के बारे में चिल्लाना होगा।

4

फायदे के बारे में:

यह हमेशा जब आप पहली बार उन्हें, पहले एक लाइन की जरूरत नहीं है चर निर्धारित करने की सिफारिश की है। यह आपके कोड की बेहतर पठनीयता के लिए है, क्योंकि कोई यह बता सकता है कि सीटींग स्क्रॉलिंग के बिना क्या है और इसे परिभाषित किया गया था।

लूप/यदि ब्लॉक पर गुंजाइश को कम करने के कारण, कोड ब्लॉक के निष्पादन के बाद परिवर्तनीय को बिना संदर्भित किया जाता है, जो इसे कचरा संग्रह के लिए उम्मीदवार बनाता है (यदि भाषा इस सुविधा का समर्थन करती है)।

2

बस कुछ एफवाईआई पुराने माइक्रोसॉफ्ट सी ++ शिकायतों में से कुछ (विजुअल स्टूडियो 6, और .NET 2003 मुझे लगता है) कुछ मामलों में स्कोपिंग नियम का पालन नहीं करते हैं।

for(int i = 0; i > 20; i++) { 
    // some code 
} 

cout << i << endl; 

मुझे दायरे से बाहर होना चाहिए, लेकिन वह वैध कोड था। मेरा मानना ​​है कि इसे एक फीचर के रूप में खेला गया था, लेकिन मेरी राय में यह सिर्फ अनुपालन नहीं है। मानकों का पालन नहीं करना बुरा है। आईई और फ़ायरफ़ॉक्स के बारे में एक वेब डेवलपर के रूप में।

वीएस के साथ कोई व्यक्ति जांच सकता है और देख सकता है कि यह अभी भी वैध है या नहीं?

+1

यह एक कंपाइलर विकल्प है, "कथन के लिए दायरे को लागू करें" या कुछ। –

+2

हाँ, यह/जेडसी: के लिए स्कोप- "लूप स्कोप के लिए मजबूती बल"। कम से कम वीएस 2008 में। –

+0

लोगों की जांच के लिए धन्यवाद। मैं अनुमान लगा रहा हूं कि यह डिफ़ॉल्ट रूप से (ब्रेकिंग स्कोप) पर है? –

0

चेतावनी संदेश को रोकने के लिए आप असाइनमेंट को() के अतिरिक्त सेट में भी संलग्न कर सकते हैं।

0

मुझे लगता है कि यह खतरनाक है। नीचे दिया गया कोड अधिक सुरक्षित है और संलग्न ब्रेसिज़ अभी भी जिस तरह से आप चाहते हैं उसे पीटिंग के दायरे को सीमित कर देगा।

मुझे लगता है कि गेटिंग() कभी-कभी न्यूल लौटाता है, इसलिए मैंने उस मजाकिया खंड को if() कथन में रखा है। यह IsReally कुछ() को एक पूर्ण सूचक पर बुलाया जाता है।

{ 
    CThing *pThing = GetThing(); 
    if(pThing ? pThing->IsReallySomeThing() : false) 
    { 
    // Do whatever 
    } 
} 
+2

सी ++ में शॉर्ट-सर्किट मूल्यांकन है, इसलिए "अगर (पीटींग और& pthing-> IsReallySomeThing())" पहले ही गारंटी देता है कि PRhing शून्य है तो IsReallySomeThing() को कॉल नहीं किया जाएगा। –

+0

डेरेक से सहमत: सच/गलत में?: हमेशा के रूप में अधिक अच्छी तरह से किया जाता है ||/&& –

0

भी ध्यान दें कि आप सी ++ कोड लिख रहे हैं अगर तुम संकलक के बारे में चेतावनी बनाना चाहते "=" एक सशर्त बयान (में है कि नहीं का हिस्सा है एक घोषणा) एक त्रुटि।

0

यह स्वीकार्य और अच्छा कोडिंग अभ्यास है। हालांकि, जो लोग निम्न स्तर की कोडिंग पृष्ठभूमि से नहीं आते हैं, वे शायद असहमत होंगे।

3
if (CThing* pThing = GetThing()) 

यह क्योंकि if अंदर आप एक बूलियन अभिव्यक्ति प्रदान नहीं कर रहे, बुरा शैली है। आप CThing* प्रदान कर रहे हैं।

CThing* pThing = GetThing(); 
if (pThing != NULL) 

यह अच्छी शैली है।