2008-10-30 6 views
36

मेरा मतलब यह है कि कार्यों, कक्षाओं, यदि, जबकि, स्विच, कोशिश-पकड़ के लिए आवश्यक होने पर इसका उपयोग करने के अलावा।क्या आप अतिरिक्त स्कोपिंग के लिए घुंघराले ब्रेसिज़ का उपयोग करते हैं?

मुझे नहीं पता था कि यह this until I saw this SO question जैसा किया जा सकता है।

उपरोक्त लिंक में, एली ने उल्लेख किया कि "वे लॉजिकल सेक्शन में अपने कोड को फोल्ड करने के लिए इसका उपयोग करते हैं जो फ़ंक्शन, क्लास, लूप इत्यादि में नहीं आते हैं जो आमतौर पर फोल्ड हो जाते हैं।"

उल्लेख किए गए अलावा अन्य उपयोग क्या हैं?

क्या आपके चर के दायरे को सीमित करने के लिए घुंघराले ब्रेसिज़ का उपयोग करना और केवल आवश्यक होने पर दायरे का विस्तार करना एक अच्छा विचार है ("आवश्यकता से पहुंच" आधार पर काम करना)? या यह वास्तव में मूर्ख है?

स्कॉप्स का उपयोग करने के बारे में कैसे करें ताकि आप अलग-अलग क्षेत्रों में समान चर नामों का उपयोग कर सकें लेकिन एक ही बड़े दायरे में? या यह एक ही वैरिएबल का पुन: उपयोग करने के लिए एक बेहतर अभ्यास है (यदि आप एक ही वैरिएबल नाम का उपयोग करना चाहते हैं) और डेलोकोकेटिंग और आवंटन पर सहेजें (मुझे लगता है कि कुछ कंपाइलर इस पर अनुकूलित कर सकते हैं?)? या अलग-अलग चर नामों का उपयोग करना बेहतर है?

+0

कृपया अपने प्रश्न को 'C# '2 साल बाद शामिल करने के लिए _retag_ नहीं करें क्योंकि यह इस पृष्ठ पर उत्तरों और टिप्पणियों को बहुत प्रभावित करता है – MickyD

उत्तर

48

मैं अगर मैं एक संसाधन जो मैं एक विशिष्ट समय जैसे पर मुक्त करना चाहते हैं का उपयोग कर रहा है:

void myfunction() 
{ 
    { 
    // Open serial port 
    SerialPort port("COM1", 9600); 
    port.doTransfer(data); 
    } // Serial port gets closed here. 

    for(int i = 0; i < data.size(); i++) 
    doProcessData(data[i]); 
    etc... 
} 
+2

YA RAII एक नया फ़ंक्शन बनाने के बजाय "अज्ञात" स्कोप का उपयोग करने का सबसे अच्छा कारण है क्योंकि RAII चर के बाध्य दायरे आमतौर पर बहुत छोटे होते हैं। –

+10

सीरियलपोर्ट लागू करने योग्य लागू करता है। संसाधन को मुक्त करने के लिए आपको 'उपयोग' ब्लॉक का उपयोग करना चाहिए। – JDB

+0

@JDB प्रश्न उस समय 'C+++' टैग किया गया था और 'C# इसलिए' IDISposable' लागू नहीं होता है। अन्यथा मैं पूरी तरह से आपके साथ सहमत हूं – MickyD

39

मैं कुछ कारणों से उस उद्देश्य के लिए घुंघराले ब्रेसिज़ का उपयोग नहीं करता।

  1. यदि आपका विशेष कार्य इतना बड़ा है कि आपको विभिन्न स्कोपिंग चाल करने की ज़रूरत है, तो शायद छोटे उप-कार्यों में फ़ंक्शन को तोड़ दें।

  2. परिवर्तनीय नामों का पुन: उपयोग करने के लिए स्कोपिंग के लिए ब्रेसिज़ पेश करना केवल कोड में भ्रम और परेशानी का कारण बन रहा है।

बस मेरे 2 सेंट, लेकिन मैंने अन्य सर्वोत्तम अभ्यास सामग्री में इन प्रकार की चीजों को देखा है।

+0

यह आम तौर पर मेरा विचार भी है - अगर मुझे कुछ छिपाने की ज़रूरत है, तो मैं सिर्फ # #region का उपयोग करता हूं 'और' # endregion' – Nobody

+0

मैं मानता हूं, स्कोपिंग के लिए फ़ंक्शंस का उपयोग किया जाना चाहिए, यदि आप अपने कार्य को समझने या लिखने में आसान बनाने के लिए अज्ञात स्कॉप्स या #region जैसे चाल का उपयोग कर रहे हैं तो आपको निश्चित रूप से इसे अन्य कार्यों में विभाजित करना चाहिए। – CamW

6

यह कोड जनरेटर के लिए एक वरदान हो सकता है। मान लें कि आपके पास एंबेडेड एसक्यूएल (ईएसक्यूएल) कंपाइलर है; यह एक SQL कथन को उस कोड के ब्लॉक में परिवर्तित करना चाहता है जिसके लिए स्थानीय चर की आवश्यकता होती है। एक ब्लॉक का उपयोग करके, यह अलग-अलग नामों के साथ सभी चर बनाने के बजाय, निश्चित चर नामों का पुन: उपयोग कर सकता है। अनुमोदित, यह बहुत कठिन नहीं है, लेकिन यह आवश्यक से कठिन है।

5

मैं केवल इसका उपयोग करता हूं जब मुझे आरएआईआई के माध्यम से कुछ जारी करने की आवश्यकता होती है और तब भी जब इसे संभवतः रिलीज़ किया जाना चाहिए (उदाहरण के लिए लॉक जारी करना)।

15

सी ++:

switch (x) { 
    case 0: 
     int i = 0; 
     foo(i); 
     break; 
    case 1: 
     int i = 1; 
     bar(i); 
     break; 
} 

कोड ऊपर संकलन नहीं करता है:

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

switch (x) { 
    case 0: 
     { 
      int i = 0; 
      foo(i); 
     } 
     break; 
    case 1: 
     { 
      int i = 1; 
      bar(i); 
     } 
     break; 
} 
+1

आपको दोनों मामलों पर एक ही चर "i" का उपयोग करने के लिए उदाहरण को ठीक करना चाहिए। यदि आप "i" और "j" का उपयोग करते हैं तो कोड ठीक से संकलित होता है। – pauloya

+0

@Paulo इसे संकलित नहीं करना चाहिए, आपको i के प्रारंभ में कूदने के लिए एक त्रुटि प्राप्त करनी चाहिए। मानक के खंड 6.7 # 3 (नोट 2 सहित) देखें। –

+0

क्षमा करें, मुझे समझ में नहीं आया कि मेरे शुरुआती दौर में कूदने के साथ आपका क्या मतलब है, क्या आपके पास सेक्शन 6.7 # 3 का लिंक है? यह मेरे स्निपेट कंपाइलर पर ठीक संकलित। – pauloya

0

मैं agartzke से सहमत हूं। अगर आपको लगता है कि आपको पठनीयता के लिए बड़े लॉजिकल कोड ब्लॉक को विभाजित करने की आवश्यकता है, तो आपको व्यस्त और अव्यवस्थित सदस्यों को साफ करने के लिए रिफैक्टरिंग पर विचार करना चाहिए।

6

जैसा कि अन्य ने कहा है, यह सशक्त आरएआईआई (संसाधन अधिग्रहण प्रारंभिक) प्रारंभिक/पैटर्न के कारण सी ++ में काफी आम है।

जावा प्रोग्रामर के लिए (और शायद सी #, मुझे नहीं पता) यह एक विदेशी अवधारणा होगी क्योंकि ढेर-आधारित वस्तुओं और जीसी ने आरएआईआई को मार दिया है। आईएमएचओ, स्टैक पर वस्तुओं को रखने में सक्षम होने के कारण जावा पर सी ++ का सबसे बड़ा लाभ है और अच्छी तरह से लिखित जावा कोड की तुलना में अच्छी तरह लिखित सी ++ कोड बहुत क्लीनर बनाता है।

+1

चेतावनी: रेंट अलर्ट! :) –

0

यह अपनी जगह है, लेकिन मुझे नहीं लगता कि कि इतना है कि $ foo यह कर एक चर यहाँ और एक अलग चर वहाँ हो सकता है, एक ही समारोह या अन्य (तार्किक, बजाय शाब्दिक) के भीतर दायरा एक अच्छा विचार है। यद्यपि संकलक पूरी तरह से समझ सकता है, ऐसा लगता है कि मनुष्य को कोड पढ़ने की कोशिश करने के लिए जीवन को मुश्किल बनाने की संभावना है।

16

स्कोपिंग का सबसे आम "गैर-मानक" उपयोग जो मैं नियमित रूप से उपयोग करता हूं वह स्कॉप्ड म्यूटेक्स का उपयोग करना है।

void MyClass::Somefun() 
{ 
    //do some stuff 
    { 
     // example imlementation that has a mutex passed into a lock object: 
     scopedMutex lockObject(m_mutex); 

     // protected code here 

    } // mutex is unlocked here 
    // more code here 
} 

यह कई फायदे हैं, लेकिन सबसे महत्वपूर्ण है कि ताला हमेशा की तरह, साफ हो जाएगा एक अपवाद संरक्षित कोड में फेंक दिया जाता है, भले ही है।

11

सबसे आम उपयोग, जैसा कि अन्य ने कहा है, यह सुनिश्चित करना है कि जब आप उन्हें चाहते हैं तो विनाशक दौड़ते हैं। यह भी प्लेटफ़ॉर्म-विशिष्ट कोड एक छोटे से साफ करने के लिए आसान है:

#if defined(UNIX) 
    if(some unix-specific condition) 
#endif 
    { 
     // This code should always run on Windows but 
     // only if the above condition holds on unix 
    } 

कोड विंडोज के लिए बनाया गया है, तो केवल ब्रेसिज़ नहीं देखता,। यह

#if defined(UNIX) 
    if(some unix-specific condition) { 
#endif 
     // This code should always run on Windows but 
     // only if the above condition holds on unix 
#if defined(UNIX) 
    } 
#endif 
1

हां, मैं इस तकनीक का उपयोग RAII के कारण करता हूं। मैं इस तकनीक का उपयोग सादा सी में भी करता हूं क्योंकि यह चर को एकसाथ करीब लाता है। बेशक, मुझे कार्यों को और भी तोड़ने के बारे में सोचना चाहिए।

एक चीज जो मैं करता हूं वह शायद स्टाइलिस्टिक रूप से विवादास्पद है, घोषणा की रेखा पर उद्घाटन घुंघराले ब्रेस डाल दिया गया है या उस पर एक टिप्पणी डाली है। I want to decrease the amount of wasted vertical space. This is based on the Google C++ Style Guide recommendation.

/// c++ code 
/// references to boost::test 
BOOST_TEST_CASE(curly_brace) 
{ 
    // init 
    MyClass instance_to_test("initial", TestCase::STUFF); { 
    instance_to_test.permutate(42u); 
    instance_to_test.rotate_left_face(); 
    instance_to_test.top_gun(); 
    } 
    { // test check 
    const uint8_t kEXP_FAP_BOOST = 240u; 
    BOOST_CHECK_EQUAL(instance_to_test.get_fap_boost(), kEXP_FAP_BOOST); 
    } 
} 
3

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

अक्सर कोड ब्लॉक एक छोटी विधि में तोड़ने के लिए बहुत छोटे होते हैं, और अक्सर फ्रेमवर्क विधि (जैसे स्टार्टअप(), या शट डाउन()) में कोड और वास्तव में कोड को एक विधि में रखना बेहतर होता है ।

व्यक्तिगत तौर पर मैं सादा चल/झूलने ब्रेसिज़ नफरत (हालांकि कि क्योंकि हम एक सख्त बैनर शैली मांगपत्र की दुकान है है), और मैं टिप्पणी मार्कर नफरत:

// yuk! 
some code 
{ 
scoped code 
} 
more code 

// also yuk! 
some code 
/* do xyz */ { 
    scoped code 
    } 
some more code 

// this I like 
some code 
DoXyz: { 
    scoped code 
    } 
some more code 

हम यदि का उपयोग करते हुए "माना (सही) { "क्योंकि जावा स्पेक विशेष रूप से कहता है कि इन्हें संकलन में अनुकूलित किया जाएगा (जैसा कि अगर (झूठी) की पूरी सामग्री होगी - यह एक डिबगिंग सुविधा है), लेकिन मुझे नफरत है कि कुछ स्थानों पर मैंने कोशिश की।

तो मुझे लगता है कि आपका विचार एक अच्छा है, बिल्कुल मूर्खतापूर्ण नहीं। मैंने हमेशा सोचा कि मैं अकेला था जो ऐसा करना चाहता था।

+0

महान विचार! यहां 8 साल बाद मैं वही काम करना चाहता हूं, धन्यवाद – stringy05

0

जिस कंपनी में मैं काम कर रहा हूं, उसमें एक कार्य की शुरुआत के पास स्थानीय परिवर्तनीय घोषणाओं को रखने के लिए एक स्थिर विश्लेषण नीति है। कई बार, फ़ंक्शन की पहली पंक्ति के बाद उपयोग कई रेखाएं होती है, इसलिए मैं स्क्रीन पर एक ही समय में घोषणा और पहला संदर्भ नहीं देख सकता। पॉलिसी को 'अवरुद्ध करने' के लिए मैं क्या करता हूं, संदर्भ के पास घोषणा रखना है, लेकिन घुंघराले ब्रेसिज़ का उपयोग करके अतिरिक्त दायरा प्रदान करना है। हालांकि यह इंडेंटेशन बढ़ाता है, और कुछ तर्क दे सकते हैं कि यह कोड को उलझन में डाल देता है।

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