C ++ कक्षाओं में सदस्य चर पर उपसर्गों का उपयोग क्यों करें


150

C ++ कोड का बहुत से सदस्य चरों को चिह्नित करने के लिए वाक्य-विन्यास का उपयोग करता है। आम उदाहरणों में शामिल हैं

  • M_ MemberName सार्वजनिक सदस्यों के लिए (जहां सार्वजनिक सदस्यों सब पर उपयोग किया जाता है)
  • _ MemberName निजी सदस्यों या सभी सदस्यों के लिए

दूसरों इस-> का उपयोग कर लागू करने के लिए कोशिश सदस्य जब भी एक सदस्य चर प्रयोग किया जाता है।

मेरे अनुभव में, अधिकांश बड़े कोड आधार ऐसे नियमों को लगातार लागू करने में विफल होते हैं।

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

क्या यह कन्वेंशन आज भी C ++ में उपयोगी है या यह सिर्फ एक आक्रोशवाद है। विशेष रूप से क्योंकि यह पुस्तकालयों में असंगत रूप से उपयोग किया जाता है। अन्य भाषाओं में नहीं दिखाया गया है कि कोई सदस्य उपसर्ग के बिना कर सकता है?


15
मैं पसंद करता हूँ; जटिल कोडबेस में यह जानना महत्वपूर्ण हो सकता है कि कौन से संस्करण स्थानीय हैं और कौन से नहीं हैं। मैं आम तौर पर इसे मजबूर करने के लिए उपसर्ग का उपयोग करता हूं-> जो मुझे बहुत अधिक अतिरिक्त टाइपिंग और वैकल्पिक लगता है (जबकि नामकरण आपको इसे करने के लिए मजबूर करेगा)
जो

5
आपने इसे विशेषता के लिए @ के कारण रूबी में कभी नहीं देखा है, और सीधे विशेषताओं का उपयोग करने के लिए प्राथमिकता में एक्सेसर्स उत्पन्न करने का मुहावरा है।
स्टीव जेसप

6
PEP के अनुसार 8 गैर-सार्वजनिक सदस्य चर को पायथन में अंडरस्कोर के साथ उपसर्ग किया जाना है (उदाहरण:) self._something = 1
नाथन उस्मान

2
क्या संपादक की वाक्य रचना हाइलाइटिंग का उपयोग इनकी पहचान के लिए नहीं किया जाना चाहिए?
भी

2
आपने this->memberपायथन कोड के बराबर देखा है । अजगर में यह आमतौर पर होगा self.memberऔर यह केवल एक सम्मेलन नहीं है, यह भाषा द्वारा आवश्यक है।
MATEC

जवाबों:


48

आपको एक प्रमुख अंडरस्कोर का उपयोग करने के साथ सावधान रहना होगा। एक शब्द में एक बड़े अक्षर से पहले एक प्रमुख अंडरस्कोर आरक्षित है। उदाहरण के लिए:

_Foo

_L

सभी आरक्षित शब्द हैं

_foo

_L

नहीं हैं। ऐसी अन्य स्थितियाँ हैं जहाँ लोअरकेस अक्षरों से पहले अंडरस्कोर की अनुमति नहीं है। मेरे विशिष्ट मामले में, मैंने पाया कि _L विजुअल C ++ 2005 द्वारा आरक्षित किया गया और क्लैश ने कुछ अप्रत्याशित परिणाम पैदा किए।

मैं इस बारे में बाड़ पर हूं कि स्थानीय चर को चिह्नित करना कितना उपयोगी है।

यहां एक लिंक है जिसके बारे में पहचानकर्ता आरक्षित हैं: C ++ पहचानकर्ता में अंडरस्कोर का उपयोग करने के बारे में क्या नियम हैं?


4
दरअसल, _foo और _l दोनों ही नेमस्पेस स्कोप में आरक्षित हैं।

13
लेकिन वे सदस्य चर नामों के रूप में ठीक हैं। मैं अंडरस्कोर उपसर्ग नहीं करता, क्योंकि नियम बहुत भ्रामक हैं, और मैं अतीत में जल गया था।
जुआन

11
ये आरक्षित शब्द नहीं हैं। वे आरक्षित नाम हैं। यदि वे आरक्षित शब्द थे, तो आप उनका उपयोग नहीं कर सकते थे। क्योंकि वे आरक्षित नाम हैं, आप उनका उपयोग कर सकते हैं, लेकिन अपने जोखिम पर।
टोनीके

235

मैं के पक्ष में सभी कर रहा हूँ अच्छी तरह से किया उपसर्गों

मुझे लगता है कि (सिस्टम) हंगेरियन संकेतन "खराब रैप" के लिए जिम्मेदार है जो उपसर्गों को मिलता है।

दृढ़ता से टाइप की गई भाषाओं में यह नोटेशन काफी हद तक व्यर्थ है जैसे कि C ++ "lpsz" में आपको यह बताने के लिए कि आपका स्ट्रिंग एक शून्य टर्मिनेटेड स्ट्रिंग के लिए एक लंबा पॉइंटर है, जब: खंडित आर्किटेक्चर प्राचीन इतिहास है, C ++ स्ट्रिंग्स आम कन्वेंशन पॉइंटर्स द्वारा nul- टर्मिनेटेड हैं। char arrays, और यह वास्तव में यह जानना मुश्किल नहीं है कि "customerName" एक स्ट्रिंग है!

हालांकि, मैं निर्दिष्ट करने के लिए उपयोग उपसर्गों कर उपयोग (हालांकि मैं वजह से यह एक बुरा और सिस्टम हंगरी के साथ अनुचित संघ होने के लिए अवधि हंगरी से बचने के लिए पसंद करते हैं, अनिवार्य रूप से "Apps हंगेरी") एक चर के लिए, और यह एक बहुत ही उपयोगी है समय बचाने वाली और बग को कम करने का तरीका।

मैं उपयोग करता हूं:

  • सदस्यों के लिए एम
  • c स्थिरांक / रीडोनॉल के लिए
  • पॉइंटर के लिए (और पॉइंटर से पॉइंटर के लिए)
  • v वाष्पशील के लिए
  • स्थिर के लिए है
  • मैं अनुक्रमित और पुनरावृत्तियों के लिए
  • ई घटनाओं के लिए

जहाँ मैं टाइप को स्पष्ट करना चाहता हूं , मैं मानक प्रत्ययों (जैसे सूची, कॉम्बोबॉक्स, आदि) का उपयोग करता हूं।

जब भी वे इसे देखते / उपयोग करते हैं, तो यह प्रोग्रामर को चर के उपयोग से अवगत कराता है। संभवतः सबसे महत्वपूर्ण मामला पॉइंटर के लिए "p" है (क्योंकि उपयोग var से बदलता है- var-> और आपको पॉइंटर्स - NULLs, पॉइंटर अंकगणितीय, आदि) के साथ और अधिक सावधान रहना होगा, लेकिन अन्य सभी बहुत काम हैं।

उदाहरण के लिए, आप किसी एकल फ़ंक्शन में एक ही चर नाम का कई तरीकों से उपयोग कर सकते हैं: (यहां C ++ उदाहरण, लेकिन यह कई भाषाओं में समान रूप से लागू होता है)

MyClass::MyClass(int numItems)
{
    mNumItems = numItems;
    for (int iItem = 0; iItem < mNumItems; iItem++)
    {
        Item *pItem = new Item();
        itemList[iItem] = pItem;
    }
}

आप यहाँ देख सकते हैं:

  • सदस्य और पैरामीटर के बीच कोई भ्रम नहीं
  • सूचकांक / पुनरावृत्ति और वस्तुओं के बीच कोई भ्रम नहीं
  • स्पष्ट रूप से संबंधित चर (आइटम सूची, सूचक और सूचकांक) के एक सेट का उपयोग करें जो "गणना", "सूचकांक" जैसे सामान्य (अस्पष्ट) नामों के कई नुकसान से बचते हैं।
  • उपसर्ग "आइटमइंडेक्स" और "क्रेडिट कार्ड" जैसे विकल्पों की तुलना में टाइपिंग को कम करते हैं (स्वतः पूर्णता के साथ बेहतर काम करते हैं)

"IName" पुनरावृत्तियों का एक और शानदार बिंदु यह है कि मैं कभी भी किसी सरणी को गलत इंडेक्स के साथ अनुक्रमित नहीं करता हूं, और यदि मैं किसी अन्य लूप के अंदर एक लूप की प्रतिलिपि बनाता हूं तो मुझे लूप इंडेक्स चर में से एक को रिफैक्ट करने की आवश्यकता नहीं है।

इस अनुचित रूप से सरल उदाहरण की तुलना करें:

for (int i = 0; i < 100; i++)
    for (int j = 0; j < 5; j++)
        list[i].score += other[j].score;

(जो पढ़ना मुश्किल है और अक्सर "i" का उपयोग करता है जहां "j" का उद्देश्य था)

साथ में:

for (int iCompany = 0; iCompany < numCompanies; iCompany++)
    for (int iUser = 0; iUser < numUsers; iUser++)
       companyList[iCompany].score += userList[iUser].score;

(जो बहुत अधिक पठनीय है, और अनुक्रमण पर सभी भ्रम को दूर करता है। आधुनिक आईडीई में ऑटो-पूर्ण के साथ, यह त्वरित और टाइप करने में आसान भी है)

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

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

(यदि आपको नहीं लगता है कि आप सामान को काम करने के लिए ऊपर और नीचे खोजने में समय बर्बाद करते हैं, तो एक साल पहले आपके द्वारा लिखे गए कुछ कोड को ढूंढें और तब से नहीं देखा है। फ़ाइल खोलें और इसे पढ़ने के बिना लगभग आधे रास्ते से नीचे कूदें। देखें। अभी तक आप इस बिंदु से पढ़ सकते हैं इससे पहले कि आप यह नहीं जानते कि क्या कोई सदस्य, पैरामीटर या स्थानीय है। अब किसी अन्य यादृच्छिक स्थान पर जाएं ... यह वह है जो हम सभी दिन भर करते हैं जब हम किसी और के कोड के माध्यम से एकल कदम रखते हैं या यह समझने की कोशिश कर रहा है कि उनके कार्य को कैसे कहा जाए)

'M' उपसर्ग भी (IMHO) बदसूरत और कृमि "इस->" "संकेतन, और उस असंगति से बचता है जो इसकी गारंटी देता है (भले ही आप सावधान रहें कि आप आमतौर पर 'इस-> डेटा' के मिश्रण से समाप्त हो जाएंगे) एक ही कक्षा में 'डेटा', क्योंकि कुछ भी नाम की लगातार वर्तनी को लागू नहीं करता है)।

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

अंतिम प्रमुख लाभ इंटेलीसेंस और ऑटो-पूरा करने के साथ है। किसी ईवेंट को खोजने के लिए विंडोज फॉर्म पर इन्टेलिसेन्स का उपयोग करने का प्रयास करें - आपको सैकड़ों रहस्यमयी बेस क्लास तरीकों से स्क्रॉल करना होगा जिन्हें आपको ईवेंट खोजने के लिए कॉल करने की आवश्यकता नहीं होगी। लेकिन अगर हर घटना में "ई" उपसर्ग होता है, तो वे स्वचालित रूप से "ई" के तहत एक समूह में सूचीबद्ध होंगे। इस प्रकार, प्रीफिक्सिंग सदस्यों, कास्ट, ईवेंट आदि को समूह की सूची में शामिल करने के लिए काम करता है, जिससे आप चाहते हैं कि नामों को खोजने में बहुत तेज और आसान हो। (आमतौर पर, एक विधि में लगभग 20-50 मान हो सकते हैं (स्थानीय, परम्स, सदस्य, कास्ट, ईवेंट) जो इसके दायरे में हैं। लेकिन उपसर्ग टाइप करने के बाद (मैं अब एक इंडेक्स का उपयोग करना चाहता हूं, इसलिए मैं टाइप करता हूं i)। .. '), मुझे केवल 2-5 ऑटो-पूर्ण विकल्पों के साथ प्रस्तुत किया गया है।' अतिरिक्त टाइपिंग '

मैं एक आलसी प्रोग्रामर हूं, और उपरोक्त सम्मेलन मुझे बहुत काम बचाता है। मैं तेजी से कोड कर सकता हूं और मैं बहुत कम गलतियां करता हूं क्योंकि मुझे पता है कि हर चर का उपयोग कैसे किया जाना चाहिए।


के खिलाफ तर्क

तो, क्या विपक्ष हैं? उपसर्गों के खिलाफ विशिष्ट तर्क हैं:

  • "उपसर्ग योजनाएँ बुरी / बुरी हैं" । मैं मानता हूं कि "m_lpsz" और इसके ilk को खराब तरीके से समझा और पूरी तरह से बेकार कर दिया गया है। इसलिए मैं आपकी आवश्यकताओं का समर्थन करने के लिए डिज़ाइन किए गए एक अच्छी तरह से नोटेशन का उपयोग करने की सलाह दूंगा, बजाय इसके कि आपके संदर्भ के लिए कुछ अनुचित हो। (इस काम के लिए सही उपकरण का उपयोग करें)।

  • "अगर मुझे किसी चीज़ का उपयोग बदलना है तो मुझे उसका नाम बदलना होगा" । हाँ, निश्चित रूप से आप करते हैं, कि क्या सभी के बारे में refactoring है, और क्यों IDEs के पास इस काम को जल्दी और दर्द रहित तरीके से करने के लिए रिफैक्टरिंग उपकरण हैं। उपसर्गों के बिना भी, चर के उपयोग को बदलने का लगभग निश्चित रूप से मतलब है कि इसका नाम बदलना चाहिए

  • "उपसर्ग सिर्फ मुझे भ्रमित करते हैं" । जैसा कि हर उपकरण तब तक करता है जब तक आप इसे इस्तेमाल करना नहीं सीखते। एक बार जब आपका मस्तिष्क नामकरण पैटर्न के लिए उपयोग हो जाता है, तो यह जानकारी को स्वचालित रूप से फ़िल्टर कर देगा और आप वास्तव में यह नहीं सोचेंगे कि उपसर्ग और भी हैं। लेकिन आपको इस योजना का उपयोग एक या दो सप्ताह के लिए ठोस रूप से करना होगा, इससे पहले कि आप वास्तव में "धाराप्रवाह" बनें। और ऐसा तब होता है जब बहुत से लोग पुराने कोड को देखते हैं और आश्चर्यचकित होते हैं कि कैसे वे कभी एक अच्छी उपसर्ग योजना के बिना प्रबंधित हुए ।

  • "मैं बस इस सामान को बाहर निकालने के लिए कोड को देख सकता हूं" । हां, लेकिन आपको कोड में कहीं और देखने में समय बर्बाद करने की जरूरत नहीं है या इसका हर छोटा-सा विवरण याद रखना होगा, जब जवाब सही हो तो आपकी आंख पहले से ही धब्बेदार हो जाती है।

  • (कुछ) कि जानकारी मेरे चर पर पॉप अप करने के लिए सिर्फ एक टूलटिप की प्रतीक्षा करके पाया जा सकता है । हाँ। जहां कुछ प्रकार के उपसर्ग के लिए समर्थित है, जब आपका कोड साफ-साफ संकलन करता है, एक प्रतीक्षा के बाद, आप एक विवरण के माध्यम से पढ़ सकते हैं और ऐसी जानकारी प्राप्त कर सकते हैं जो उपसर्ग ने तुरंत बताई होगी। मुझे लगता है कि उपसर्ग एक सरल, अधिक विश्वसनीय और अधिक कुशल दृष्टिकोण है।

  • "यह अधिक टाइपिंग है" । वास्तव में? एक पूरे चरित्र अधिक? या यह है - आईडीई ऑटो-पूर्ण उपकरणों के साथ, यह अक्सर टाइपिंग कम कर देगा, क्योंकि प्रत्येक उपसर्ग चरित्र खोज स्थान को महत्वपूर्ण रूप से बढ़ाता है। प्रेस "ई" और आपकी कक्षा की तीन घटनाएं अंतर्कलह में पॉप अप होती हैं। प्रेस "सी" और पांच स्थिरांक सूचीबद्ध हैं।

  • "मैं this->इसके बजाय उपयोग कर सकता हूं m" । खैर, हाँ, आप कर सकते हैं। लेकिन यह सिर्फ एक बहुत बदसूरत और अधिक क्रिया उपसर्ग है! केवल यह बहुत अधिक जोखिम (विशेषकर टीमों में) वहन करता है क्योंकि संकलक के लिए यह वैकल्पिक है , और इसलिए इसका उपयोग अक्सर असंगत है। mदूसरी ओर संक्षिप्त, स्पष्ट, स्पष्ट और वैकल्पिक नहीं है, इसलिए इसका उपयोग करने में गलती करना बहुत कठिन है।


6
मेरा तात्पर्य यह है कि पढ़ने के साथ ही हंगरियन नोटेशन की समस्या सिमोनी को गलत समझी गई थी। उन्होंने लिखा कि उपसर्ग का उपयोग एक चर के प्रकार को इंगित करने के लिए किया जाना चाहिए, जहां उनका मतलब "प्रकार" की तरह "तरह की" है, न कि शाब्दिक डेटाटाइप। बाद में Microsoft के प्लेटफ़ॉर्म वालों ने इसे उठाया और lpsz के साथ आया ... और बाकी इतिहास है ...
VoidPointer

19
"स्थैतिक के लिए है" मेरे लिए हंगरी के "खराब" रूप की तरह बहुत अच्छा लगता है।
jalf

6
@ मेहरदाद: मुझे नहीं लगता कि zसी ++ जैसी भाषा में बहुत उपयोगी है, जहां उस तरह के निम्न स्तर के कार्यान्वयन विस्तार को एक कक्षा में समझाया जाना चाहिए, लेकिन सी में (जहां शून्य-समाप्ति एक महत्वपूर्ण अंतर है) मैं आपसे सहमत हूं। IMO का उपयोग करने वाली किसी भी योजना को हमारी अपनी आवश्यकताओं के अनुसार सबसे उपयुक्त होने के लिए अनुकूलित किया जाना चाहिए - इसलिए, यदि शून्य-समाप्ति आपके चर के उपयोग को प्रभावित करती है, तो "z" को एक उपयोगी उपसर्ग घोषित करने में कुछ भी गलत नहीं है।
जेसन विलियम्स

14
The most important case is "p" for pointer (because the usage changes from var. to var-> and you have to be much more careful with pointers.मैं पूरे दिल से असहमत हूं। अगर मैं एक पॉइंटर गलत का उपयोग करता हूं, तो यह बस संकलन नहीं करेगा ( void*हालांकि डबल पॉइंटर्स के लिए एक अपवाद हो सकता है)। और पूरा ->ओवर .मुझे यह बताने के लिए काफी है कि यह एक पॉइंटर है। इसके अलावा, यदि आप स्वत: पूर्ण का उपयोग कर रहे हैं, तो आपके संपादक के पास संभवतः घोषणा टूलटिप्स हैं, जो चर जानकारी के लिए उपसर्ग की आवश्यकता को समाप्त करते हैं। भले ही, अच्छा जवाब।
थॉमस एडिंग

5
स्पष्ट, व्यापक और दिलचस्प व्याख्याओं के लिए तैयार, हालांकि यहाँ यह बताने का बहुत कम प्रयास है कि यह C ++ YET में समय कैसे बचाता है, यह कई अन्य भाषाओं में काफी हद तक अप्रयुक्त रहता है।

115

मैं आम तौर पर सदस्य चर के लिए एक उपसर्ग का उपयोग नहीं करता हूं।

मैं किसी mउपसर्ग का उपयोग करता था , जब तक कि कोई यह नहीं बताता कि "सी ++ में पहले से ही सदस्य पहुंच के लिए एक मानक उपसर्ग है this->:।

इसलिए अब मैं इसका उपयोग करता हूं। यही है, जब अस्पष्टता होती है , तो मैं this->उपसर्ग जोड़ता हूं , लेकिन आमतौर पर, कोई अस्पष्टता मौजूद नहीं होती है, और मैं सीधे चर नाम का उल्लेख कर सकता हूं।

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

बेशक, इस के लिए स्पष्ट काउंटर "हाँ, लेकिन फिर आप एक नज़र में नहीं देख सकते हैं कि एक चर वर्ग का सदस्य है या नहीं"।

जिस पर मैं कहता हूं "तो क्या? अगर आपको यह जानना है कि, आपकी कक्षा में शायद बहुत अधिक राज्य हैं। या फ़ंक्शन बहुत बड़ा और जटिल है"।

व्यवहार में, मैंने पाया है कि यह बहुत अच्छी तरह से काम करता है। एक अतिरिक्त बोनस के रूप में यह मुझे नाम बदलने के लिए बिना, एक वर्ग सदस्य (या आसपास के अन्य तरीके) के लिए एक स्थानीय चर को बढ़ावा देने की अनुमति देता है।

और सबसे अच्छा, यह सुसंगत है! मुझे कुछ खास करने की ज़रूरत नहीं है या निरंतरता बनाए रखने के लिए किसी भी सम्मेलन को याद नहीं करना है।


वैसे, आपको अपने वर्ग के सदस्यों के लिए अग्रणी अंडरस्कोर का उपयोग नहीं करना चाहिए । आप उन नामों के करीब पहुंच सकते हैं जो कार्यान्वयन द्वारा आरक्षित हैं।

मानक में डबल अंडरस्कोर या अंडरस्कोर के साथ शुरू होने वाले सभी नाम होते हैं, जिसके बाद कैपिटल लेटर होता है। यह वैश्विक नामस्थान में एकल अंडरस्कोर के साथ शुरू होने वाले सभी नामों को भी रखता है ।

इसलिए निचले मामले वाले पत्र के बाद एक प्रमुख अंडरस्कोर वाला एक वर्ग का सदस्य कानूनी है, लेकिन जितनी जल्दी या देर से आप ऊपरी मामले से शुरू होने वाले पहचानकर्ता के लिए ऐसा करने जा रहे हैं, या अन्यथा उपरोक्त नियमों में से एक को तोड़ दें।

इसलिए केवल प्रमुख अंडरस्कोर से बचना आसान है। एक पोस्टफ़िक्स अंडरस्कोर, या एक का उपयोग करें m_या सिर्फ mउपसर्ग अगर आप वैरिएबल नाम में एनकोड गुंजाइश करना चाहते हैं।


"तो एक निचले मामले के बाद एक प्रमुख अंडरस्कोर वाला एक वर्ग का सदस्य कानूनी है, लेकिन जितनी जल्दी या देर से आप ऊपरी मामले से शुरू होने वाले पहचानकर्ता के लिए ऐसा करने जा रहे हैं, या अन्यथा उपरोक्त नियमों में से एक को तोड़ दें।" - क्लास मेंबर वैरिएबल ग्लोबल नेमस्पेस में नहीं हैं, इसलिए एक प्रमुख अंडरस्कोर सुरक्षित है, फिर चाहे वह कम हो या अपरकेस अक्षर।
mbarnett

3
@mbarnett: नहीं, अपर-केस के बाद अंडरस्कोर सामान्य रूप से आरक्षित है , न कि केवल वैश्विक नामस्थान में।
jalf

9
आश्चर्य है कि इस उत्तर का वोट उपसर्ग से कम है।
मार्सन माओ

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

इसके अलावा, आपको अपने कोड को अन्य लोगों को देने के लिए अपने सम्मेलन का दस्तावेजीकरण करने की आवश्यकता नहीं है। हर कोई समझता है कि this->इसका क्या मतलब है।
काडूचेन

34

मैं पोस्टफ़िक्स अंडरस्कोर पसंद करता हूं, जैसे:

class Foo
{
   private:
      int bar_;

   public:
      int bar() { return bar_; }
};

मैं भी। मैं एक्सेसर्स / म्यूटेटर्स को भी यही नाम देता हूं।
रोब

4
दिलचस्प। पहले थोड़ा बदसूरत लगता है, लेकिन मैं देख सकता हूं कि यह कैसे फायदेमंद हो सकता है।
यंहा

6
मैं कहता हूँ कि यह बहुत कम बदसूरत है: "mBar" या "m_bar"।
सिदंन

6
लेकिन तब आपके पास है vector<int> v_;और लेखन v_.push_back(5)बहुत बदसूरत है
21

4
वह Google C ++ शैली है।
Justme0

20

हाल ही में मैं बिना किसी उपसर्ग के होने के बजाय m_ उपसर्ग पसंद करना पसंद कर रहा हूं, कारण इतना नहीं है कि सदस्य चर को ध्वजांकित करना महत्वपूर्ण है, लेकिन यह अस्पष्टता से बचा जाता है, कहते हैं कि आपके पास कोड है:

void set_foo(int foo) { foo = foo; }

यह कारण काम नहीं करता है, केवल एक ही fooअनुमति देता है। तो आपके विकल्प हैं:

  • this->foo = foo;

    मुझे यह पसंद नहीं है, क्योंकि यह पैरामीटर को छाया देने का कारण बनता है, आप अब g++ -Wshadowचेतावनियों का उपयोग नहीं कर सकते हैं , यह भी टाइप करने के लिए लंबा है m_। तुम भी अभी भी चर और कार्यों के बीच संघर्ष नामकरण आप एक है जब में चलाने int foo;के लिए और एक int foo();

  • foo = foo_; या foo = arg_foo;

    कुछ समय के लिए इसका उपयोग किया गया, लेकिन यह तर्क को बदसूरत बनाता है, प्रलेखन को कार्यान्वयन में नाम की असहमति के साथ सौदा नहीं करना चाहिए। वैरिएबल और फ़ंक्शंस के बीच नामकरण संघर्ष भी यहाँ मौजूद हैं।

  • m_foo = foo;

    एपीआई प्रलेखन साफ ​​रहता है, तो आपको सदस्य कार्यों और चर के बीच अस्पष्टता नहीं मिलती है और इसके बाद टाइप करने के लिए छोटा होता है this->। केवल नुकसान यह है कि यह POD संरचनाओं को बदसूरत बना देता है, लेकिन चूंकि POD संरचनाएं पहले स्थान पर नाम की अस्पष्टता से ग्रस्त नहीं हैं, इसलिए किसी को उनके साथ इसका उपयोग करने की आवश्यकता नहीं है। एक अद्वितीय उपसर्ग होने से कुछ खोज भी होती है और परिचालन को आसान बनाता है।

  • foo_ = foo;

    m_लागू होने के अधिकांश फायदे , लेकिन मैं इसे सौंदर्य कारणों से अस्वीकार करता हूं, एक अनुगामी या अग्रणी अंडरस्कोर सिर्फ चर को अपूर्ण और असंतुलित बनाता है। m_बस बेहतर लग रहा है। का उपयोग करना m_भी अधिक विस्तार योग्य है, जैसा कि आप g_ग्लोबल्स और s_स्टेटिक्स के लिए उपयोग कर सकते हैं ।

पुनश्च: आप m_पायथन या रूबी में क्यों नहीं देखते हैं इसका कारण यह है कि दोनों भाषाएं अपने स्वयं के उपसर्ग को लागू करती हैं, रूबी @सदस्य चर के लिए उपयोग करती है और पायथन की आवश्यकता होती है self.


1
निष्पक्ष होने के लिए, आप कम से कम 2 अन्य विकल्पों को याद करते हैं, उदाहरण के लिए (ए) fooकेवल सदस्यों के लिए पूर्ण नाम का उपयोग करते हैं और इसके बजाय मापदंडों या अन्य स्थानीय लोगों / फेंकवे के लिए एकल-पत्र या संक्षिप्त नामों का उपयोग करते हैं, जैसे int f; या (बी) कुछ के साथ मापदंडों या अन्य स्थानीय लोगों को उपसर्ग करें । अच्छी बात फिर से m_और फली, हालांकि; मैं स्वतंत्र रूप से सबसे अधिक भाग के लिए उन दोनों दिशानिर्देशों का पालन करने के लिए एक प्राथमिकता पर आया हूं।
अंडरस्कोर_ड

12

जब एक सदस्य फ़ंक्शन के माध्यम से पढ़ते हैं, तो यह जानना कि प्रत्येक चर का "मालिक" कौन है, चर का अर्थ समझने के लिए बिल्कुल आवश्यक है। इस तरह एक समारोह में:

void Foo::bar( int apples )
{
    int bananas = apples + grapes;
    melons = grapes * bananas;
    spuds += melons;
}

... यह देखना काफी आसान है कि सेब और केले कहां से आ रहे हैं, लेकिन अंगूर, खरबूजे और चम्मच के बारे में क्या? क्या हमें वैश्विक नामस्थान में देखना चाहिए? वर्ग घोषणा में? चर इस वस्तु का सदस्य है या इस वस्तु वर्ग का सदस्य है? इन सवालों के जवाब को जाने बिना, आप कोड को नहीं समझ सकते। और एक लंबे कार्य में, यहां तक ​​कि सेब और केले जैसे स्थानीय चर की घोषणा भी फेरबदल में खो सकती है।

ग्लोबल्स, सदस्य चर और स्थिर सदस्य चर (शायद g_, m_, और s_ क्रमशः) के लिए एक सुसंगत लेबल को प्रस्तुत करना तुरंत स्थिति को स्पष्ट करता है।

void Foo::bar( int apples )
{
    int bananas = apples + g_grapes;
    m_melons = g_grapes * bananas;
    s_spuds += m_melons;
}

इनमें से कुछ को पहली बार में इस्तेमाल करने में मदद मिल सकती है - लेकिन फिर, प्रोग्रामिंग में क्या नहीं है? एक दिन ऐसा भी था जब आपको भी {और} अजीब लग रहे थे। और एक बार जब आप उनके लिए अभ्यस्त हो जाते हैं, तो वे कोड को अधिक तेज़ी से समझने में आपकी सहायता करते हैं।

(M_ के स्थान पर "इस->" का उपयोग करना समझ में आता है, लेकिन इससे भी अधिक लंबी-घुमावदार और नेत्रहीन विघटनकारी है। मैं इसे सदस्य चर के सभी उपयोगों को चिह्नित करने के लिए एक अच्छे विकल्प के रूप में नहीं देखता हूं।)

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

void Foo::bar( int iApples )
{
    int iBananas = iApples + g_fGrapes;
    m_fMelons = g_fGrapes * iBananas;
    s_dSpuds += m_fMelons;
}

हंगेरियन करता हैहमें कोड के बारे में कुछ नया बताएं। अब हम समझते हैं कि फू :: बार () फ़ंक्शन में कई निहित कलाकार हैं। कोड के साथ समस्या अब यह है कि हंगेरियन उपसर्गों द्वारा जोड़ी गई जानकारी का मूल्य दृश्य लागत के सापेक्ष छोटा है। C ++ टाइप सिस्टम में कई प्रकार के फीचर्स शामिल हैं जो या तो एक साथ काम करने में मदद करते हैं या कंपाइलर वार्निंग या एरर बढ़ाने के लिए। संकलक हमें प्रकारों से निपटने में मदद करता है - हमें ऐसा करने के लिए अंकन की आवश्यकता नहीं है। हम आसानी से पर्याप्त अनुमान लगा सकते हैं कि फू :: बार () में चर संभवतः संख्यात्मक हैं, और यदि हम जानते हैं, तो यह फ़ंक्शन की सामान्य समझ प्राप्त करने के लिए पर्याप्त है। इसलिए प्रत्येक चर के सटीक प्रकार को जानने का मूल्य अपेक्षाकृत कम है। फिर भी "s_dSpuds" (या यहां तक ​​कि "dSpuds") जैसे चर की कुरूपता महान है। इसलिए,


S_ विचार के लिए धन्यवाद। बहुत उपयोगी लगता है, और किसी भी तरह मेरे लिए कभी नहीं हुआ था।
क्रिस ऑलसेन

10

मैं यह नहीं कह सकता कि यह कैसा है, लेकिन व्यक्तिगत रूप से बोलते हुए, मैंने हमेशा (और हमेशा) अपने सदस्य चर को '' 'के साथ उपसर्ग किया। उदाहरण के लिए:

class Person {
   .... 
   private:
       std::string mName;
};

यह मेरे द्वारा उपयोग किए जाने वाले उपसर्ग का एकमात्र रूप है (मैं हंगेरियन विरोधी बहुत विरोधी हूं) लेकिन इसने मुझे वर्षों से अच्छी स्थिति में खड़ा किया है। एक तरफ के रूप में, मैं आम तौर पर नामों (या उस मामले के लिए कहीं और) में अंडरस्कोर का उपयोग का पता लगाता हूं, लेकिन प्रीप्रोसेसर मैक्रो नामों के लिए एक अपवाद बनाते हैं, क्योंकि वे आमतौर पर सभी बड़े होते हैं।


5
M_ (या _) के बजाय m का उपयोग करने में समस्या, ऊंट के मामले के लिए वर्तमान फैशन के साथ है, इससे कुछ चर नामों को पढ़ना मुश्किल हो जाता है।
मार्टिन बेकेट

1
@ नील मैं तुम्हारे साथ हूँ। @ एमजीबी: मुझे '_' से शुरू होने वाले नामों से नफरत है। यह भविष्य में गलत होने वाली चीजों के लिए सिर्फ एक निमंत्रण है।
मार्टिन यॉर्क

1
@ नील: आप किस अधिवेशन का उपयोग करते हैं, यदि आप अंडरस्कोर का उपयोग नहीं करते हैं, और ऊंट का उपयोग नहीं करते हैं?
जलफ

2
मेरी समझ यह थी कि यह कैमकेलेज़ है जो vari एपीडाटा ’जैसे भ्रमित करने के लिए सिर्फ एम का उपयोग करता है - यह _ मैप_डेटा’ के बजाय _ मैप_डेटा ’बन जाता है। मैं संरक्षित / निजी सदस्य चर के लिए _camelCase का उपयोग करता हूं क्योंकि यह बाहर खड़ा है
मार्टिन बेकेट

10
@MartinBeckett: आपको aउस परिदृश्य में पूंजीकरण करना चाहिए - आप इसे अन्यथा नहीं कर रहे हैं। mApData( mउपसर्ग, तब चर नाम है apData)।
प्लेटिनम एज़्योर

8

एक सदस्य उपसर्ग का मुख्य कारण एक सदस्य फ़ंक्शन स्थानीय और एक ही नाम के साथ एक सदस्य चर के बीच अंतर करना है। यह उपयोगी है यदि आप चीज के नाम के साथ गेटर्स का उपयोग करते हैं।

विचार करें:

class person
{
public:
    person(const std::string& full_name)
        : full_name_(full_name)
    {}

    const std::string& full_name() const { return full_name_; }
private:
    std::string full_name_;
};

इस मामले में सदस्य चर को full_name नहीं कहा जा सकता है। आपको get_full_name () में सदस्य फ़ंक्शन का नाम बदलने या सदस्य चर को किसी तरह सजाने की आवश्यकता है।


1
यही कारण है कि मैं उपसर्ग करता हूं। मुझे लगता foo.name()है कि foo.get_name()मेरे विचार से बहुत अधिक पठनीय है ।
टेराबिट्स

6

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

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

void myFunc(int index){
  this->index = index;
}

void myFunc(int index){
  m_index = index;
}

मैं इसका इस्तेमाल दोनों को अलग करने के लिए करता हूं। इसके अलावा जब मैं कॉल को लपेटता हूं, जैसे कि Dll से Windows Dll, RecvPacket (...) को मेरे कोड में RecvPacket (...) में लपेटा जा सकता है । "_" जैसे उपसर्ग का उपयोग करने वाले इन विशेष अवसरों में दोनों को समान रूप से देखा जा सकता है, यह पहचानना आसान है कि कौन सा है, लेकिन संकलक के लिए अलग है


6

कुछ जवाबों ने पठनीयता में सुधार के तरीके के रूप में, सम्मेलनों के नामकरण के बजाय, रिफैक्टरिंग पर ध्यान केंद्रित किया है। मुझे नहीं लगता कि कोई दूसरे की जगह ले सकता है।

मुझे ऐसे प्रोग्रामर ज्ञात हैं जो स्थानीय घोषणाओं का उपयोग करने में असहज होते हैं; वे सभी घोषणाओं को एक ब्लॉक के शीर्ष पर रखना पसंद करते हैं (जैसा कि सी में), इसलिए वे जानते हैं कि उन्हें कहां खोजना है। मैंने पाया है कि, जहाँ स्कूपिंग इसके लिए अनुमति देता है, चरों की घोषणा करते हुए, जहाँ वे पहली बार उपयोग किए जाते हैं, उस समय को कम कर देता है, जिसे मैं घोषणाओं को खोजने के लिए पीछे की ओर देखते हुए खर्च करता हूँ। (यह मेरे लिए छोटे कार्यों के लिए भी सच है।) इससे मुझे उस कोड को समझने में आसानी होती है जो मैं देख रहा हूं।

मुझे आशा है कि यह स्पष्ट है कि यह सदस्य नामकरण सम्मेलनों से कैसे संबंधित है: जब सदस्य समान रूप से उपसर्ग करते हैं, तो मुझे कभी भी पीछे मुड़कर नहीं देखना चाहिए; मुझे पता है कि घोषणा भी स्रोत फ़ाइल में नहीं मिलेगी।

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


5

उन सम्मेलनों बस रहे हैं। ज्यादातर दुकानें कोड कन्वेंशन को कोड पठनीयता को कम करने के लिए उपयोग करती हैं ताकि कोई भी आसानी से कोड के एक टुकड़े को देख सके और सार्वजनिक और निजी सदस्यों जैसे चीजों के बीच जल्दी से व्याख्या कर सके।


"सार्वजनिक और निजी सदस्यों जैसी चीजों के बीच" - यह वास्तव में कितना आम है? मुझे यह देखकर याद नहीं है, लेकिन फिर, मैं कोडबेस या कुछ भी समीक्षा नहीं करता।
अंडरस्कोर_ड

मैं इसे अपने कोडिंग में नहीं करता हूं, लेकिन मैंने उन जगहों पर काम किया है जहां हमें उनके कोड कन्वेंशन गाइड के आधार पर करना था। मैं ऐसा नहीं करना पसंद करता हूं क्योंकि लगभग सभी आईडीई निजी चर को अलग रंग दिखाएंगे।
मिस्टर विल २

हम्म, मुझे लगता है कि यह केवल खान से अलग स्थितियों में होता है। आम तौर पर मैं या तो classउन सभी का उपयोग करता हूं जिनके सभी सदस्य private/ protected, या POD structहैं जिनके सभी चर public(और अक्सर भी const) हैं। इसलिए, मुझे किसी भी सदस्य के पहुँच स्तर के बारे में आश्चर्य करने की आवश्यकता नहीं है।
अंडरस्कोर_ड

5

जब भी कोई सदस्य चर का उपयोग करता है तो अन्य लोग इसका उपयोग करने की कोशिश करते हैं

वह आमतौर पर है क्योंकि कोई उपसर्ग नहीं है । संकलक को प्रश्न में चर को हल करने के लिए पर्याप्त जानकारी की आवश्यकता होती है, यह उपसर्ग के कारण या thisकीवर्ड के माध्यम से एक अनूठा नाम है ।

तो, हाँ, मुझे लगता है कि उपसर्ग अभी भी उपयोगी हैं। मैं, एक के लिए, '_-' टाइप करने के बजाय किसी सदस्य तक पहुँचने के लिए '_' टाइप करना पसंद करूँगा।


3
संकलक इसे किसी भी तरह से हल कर सकता है ... स्थानीय चर अधिकांश लैंग्यूज में उच्च दायरे में छिपाएंगे। यह कोड पढ़ने वाले मनुष्यों के (संदिग्ध) लाभ के लिए है। कोई भी सभ्य
आईडी

1
बिल्कुल सही। स्थानीय लोग वर्ग के सदस्यों को छिपाएंगे। एक निर्माणकर्ता पर विचार करें जो इन सदस्यों को सेट करता है। आमतौर पर यह पैरामीटर के सदस्यों के नाम के समान समझ में आता है।
केंट बोगारार्ट

6
क्यों एक कोड गंध है? मैं कहता हूं कि यह पूरी तरह से सामान्य और उचित है, खासकर जब यह निर्माणकर्ताओं की बात आती है।
केंट बोगारार्ट

3
एक रचनाकार को (आमतौर पर) स्थानीय लोगों को अपनी प्रारंभिक सूची में सेट करना चाहिए। और वहाँ पैरामीटर, क्षेत्र के नाम को छाया नहीं देते हैं, लेकिन दोनों सुलभ हैं - इसलिए आप लिख सकते हैंstruct Foo { int x; Foo(int x) : x(x) { ... } };
पावेल मिनावे

2
मुझे लगता है कि समस्या तब आती है जब आप करते हैं कि Foo(int x, bool blee) : x(x) { if (blee) x += bleecount; } // oops, forgot this->मैं अपने सदस्य चर को कुछ उपयोगी कहना पसंद करता हूं और फिर निर्माण मानकों को देता हूं जो उन्हें संक्षिप्त नामों से मेल खाते हैं:Foo(int f) : foo(f) {...}
स्टीव जेसप

4

अन्य भाषाओं में कोडिंग सम्मेलनों का उपयोग किया जाएगा, वे बस अलग हो जाते हैं। C # उदाहरण के लिए संभवतः दो अलग-अलग शैलियाँ हैं, जिनका उपयोग लोग करते हैं, या तो C ++ विधियों में से एक (_variable, mVariable या अन्य उपसर्ग जैसे हंगेरियन नोटेशन), या जिसे मैं StyleCop विधि के रूप में संदर्भित करता हूं।

private int privateMember;
public int PublicMember;

public int Function(int parameter)
{
  // StyleCop enforces using this. for class members.
  this.privateMember = parameter;
}

अंत में, यह वही बन जाता है जो लोग जानते हैं, और जो सबसे अच्छा दिखता है। मुझे व्यक्तिगत रूप से लगता है कि कोड हंगेरियन अंकन के बिना अधिक पठनीय है, लेकिन उदाहरण के लिए इंटेलीजेंस के साथ एक चर खोजना आसान हो सकता है अगर हंगेरियन अंकन जुड़ा हुआ है।

ऊपर मेरे उदाहरण में, आपको सदस्य चर के लिए m उपसर्ग की आवश्यकता नहीं है क्योंकि इस के साथ आपके उपयोग को उपसर्ग करना। एक संकलक-विधि में एक ही बात को इंगित करता है।

इसका मतलब यह नहीं है कि अन्य तरीके खराब हैं, लोग क्या काम करते हैं।


3

जब आपके पास एक बड़ी विधि या कोड ब्लॉक होता है, तो यह तुरंत जानना आसान होता है कि क्या आप स्थानीय चर या सदस्य का उपयोग करते हैं। यह त्रुटियों से बचने और बेहतर निर्मलता के लिए है!


3
यदि आपके पास एक बड़ी विधि है, तो बेहतर तरीके से इसे साफ करने के लिए।
sbi

4
कुछ बड़े तरीकों को न तोड़ने के बहुत सारे कारण हैं। उदाहरण के लिए, यदि आपकी विधि को बहुत अधिक स्थानीय स्थिति रखने की आवश्यकता है, तो आपको या तो अपने अधीनस्थ विधियों में बहुत सारे मापदंडों को पास करना होगा, इन वर्गों के बीच डेटा पारित करने के लिए या राज्य डेटा घोषित करने के उद्देश्य से नई कक्षाएं बनाएं। माता-पिता वर्ग का सदस्य डेटा। इन सभी में ऐसी समस्याएं हैं जो एकल लंबी-ईश विधि (विशेषकर जिसका तर्क सीधा है) की तुलना में विधि की स्पष्टता या स्थिरता को प्रभावित करती है।
स्टीव ब्रबर्ग

3
@ एसबीआई: दिशानिर्देश सिर्फ इतना ही है; दिशानिर्देश, नियम नहीं। कभी-कभी आपको बड़े तरीकों की आवश्यकता होती है जो तार्किक रूप से विभाजित होने के लिए खुद को उधार नहीं देते हैं, और कभी-कभी पैरामीटर नाम सदस्यों के साथ टकराव करते हैं।
एड एस।

कृपया अपने सदस्य चर को सार्वजनिक न करें। बस एक्सेसर्स का उपयोग करें। कोष्ठकों को पाठक को बताना चाहिए कि यह एक सदस्य चर है।
jkeys

ध्यान दें कि नामों के टकराव का पता लगाने के लिए gcc (> = 4.6) में एक चेतावनी है:-Wshadow
Caduchon

3

IMO, यह व्यक्तिगत है। मैं कोई उपसर्ग नहीं लगा रहा हूं। वैसे भी, अगर कोड को सार्वजनिक किया जाता है, तो मुझे लगता है कि इसमें कुछ उपसर्ग होने चाहिए, इसलिए यह अधिक पठनीय हो सकता है।

अक्सर बड़ी कंपनियां इसका उपयोग कर रही हैं, इसलिए यह तथाकथित 'डेवलपर नियम' हैं।
Btw, सबसे मजेदार अभी तक होशियार मैं देखा सूखी चुंबन था (न दोहराएँ खुद को। यह सरल रखें, बेवकूफ)। :-)


3

जैसा कि दूसरों ने पहले ही कहा है, महत्व बोलचाल का है (नामकरण की शैली और कोड आधार पर कन्वेंशन जिसमें आप लिख रहे हैं) और सुसंगत होना।

सालों से मैंने एक बड़े कोड बेस पर काम किया है जो पोस्टफ़िक्स का उपयोग करने के साथ-साथ "यह->" सम्मेलन दोनों का उपयोग करता है मेंबर वेरिएबल के लिए अंडरस्कोर नोटेशन । वर्षों के दौरान मैंने छोटी परियोजनाओं पर भी काम किया है, जिनमें से कुछ का नाम सदस्य चर के लिए किसी भी प्रकार का सम्मेलन नहीं था, और अन्य जिनके नाम सदस्य चर नामकरण के लिए अलग-अलग सम्मेलन थे। उन छोटी परियोजनाओं में से, मैंने लगातार उन लोगों को पाया है जिनके पास जल्दी से कूदने और समझने में सबसे कठिन होने के लिए किसी भी सम्मेलन का अभाव था।

मैं नामकरण के बारे में बहुत गुदा-प्रतिशोधी हूं। मैं एक वर्ग या चर को इंगित करने के लिए इस नाम पर सहमत हो जाऊंगा कि, अगर मुझे कुछ ऐसा नहीं आता है जो मुझे लगता है कि "अच्छा" है, तो मैं इसे कुछ निरर्थक नाम देना चुनूंगा और एक टिप्पणी प्रदान करूंगा जो वास्तव में वर्णन करता है। है। इस तरह, कम से कम नाम का मतलब वही है जो मैं इसका मतलब चाहता हूं - इससे ज्यादा और कुछ भी कम नहीं। और अक्सर, थोड़ी देर के लिए इसका उपयोग करने के बाद, मुझे पता चलता है कि नाम वास्तव में क्या होना चाहिए और उचित रूप से वापस जा सकता है और संशोधित कर सकता है या रिफ्लेक्टर कर सकता है।

एक आईडीई के काम करने के विषय पर एक अंतिम बिंदु - यह सब अच्छा और अच्छा है, लेकिन आईडीई अक्सर उन वातावरण में उपलब्ध नहीं होते हैं जहां मैंने सबसे जरूरी काम किया है। कभी-कभी उस बिंदु पर उपलब्ध एकमात्र चीज 'vi' की एक प्रति होती है। इसके अलावा, मैंने कई मामलों को देखा है जहां आईडीई कोड पूरा होने ने नामों में गलत वर्तनी जैसी मूर्खता का प्रचार किया है। इस प्रकार, मैं एक आईडीई बैसाखी पर भरोसा नहीं करना चाहता।


3

C ++ सदस्य चर पर उपसर्गों के लिए मूल विचार अतिरिक्त प्रकार की जानकारी संग्रहीत करना था जिसके बारे में संकलक को जानकारी नहीं थी। इसलिए, उदाहरण के लिए, आपके पास एक स्ट्रिंग हो सकती है जो वर्णों की निश्चित लंबाई है, और दूसरा वह चर है जिसे '\ 0' द्वारा समाप्त किया गया है। संकलक के लिए वे दोनों हैं char *, लेकिन अगर आप एक से दूसरे में कॉपी करने की कोशिश करते हैं तो आपको भारी परेशानी होती है। तो, मेरे सिर के ऊपर से,

char *aszFred = "Hi I'm a null-terminated string";
char *arrWilma = {'O', 'o', 'p', 's'};

जहाँ "asz" का अर्थ है कि यह चर "ascii string (शून्य-टर्मिनेटेड)" और "arr" है, जिसका अर्थ है कि यह चर वर्ण सरणी है।

फिर जादू होता है। कंपाइलर इस कथन से पूरी तरह खुश होगा:

strcpy(arrWilma, aszFred);

लेकिन आप, एक मानव के रूप में, इसे देख सकते हैं और कह सकते हैं "अरे, वे चर वास्तव में एक ही प्रकार के नहीं हैं, मैं ऐसा नहीं कर सकता"।

दुर्भाग्य से बहुत से स्थान चर चर के लिए "m_" जैसे मानकों का उपयोग करते हैं, पूर्णांक के लिए "i" कोई फर्क नहीं पड़ता कि कैसे उपयोग किया जाता है, चार बिंदुओं के लिए "cp"। दूसरे शब्दों में, वे संकलक को जानते हैं और उसी समय पढ़ने के लिए कोड को कठिन बना रहे हैं। मेरा मानना ​​है कि इस भयावह प्रथा को क़ानून के दायरे से बाहर किया जाना चाहिए और कठोर दंड के अधीन होना चाहिए।

अंत में, दो बिंदु हैं जिनका मुझे उल्लेख करना चाहिए:

  • C ++ फीचर्स का विवेकपूर्ण उपयोग कंपाइलर को उन जानकारियों को जानने की अनुमति देता है, जिन्हें आपको कच्चे सी-स्टाइल वैरिएबल में एनकोड करना था। आप ऐसी कक्षाएं बना सकते हैं जो केवल वैध संचालन की अनुमति देंगी। यह उतना ही किया जाना चाहिए जितना व्यावहारिक हो।
  • अपने कोड ब्लॉक इतने लंबे समय है कि आप भूल जाते हैं कर रहे हैं क्या एक चर टाइप इससे पहले कि आप इसका इस्तेमाल करते हैं वे कर रहे हैं है, जिस तरह से बहुत लंबा है। नामों का उपयोग न करें, फिर से व्यवस्थित करें।

उपसर्ग जो प्रकार या प्रकार के चर को इंगित करते हैं, वे भी एक चर्चा के लायक हैं, लेकिन मैं मुख्य रूप से उपसर्गों का उल्लेख कर रहा था कि क्या कोई (निजी) सदस्य / क्षेत्र है। जब आप उल्लेख कर रहे हों तो उल्टा हंगेरियन अंकन काफी समझदारी से लागू किया जा सकता है (जैसे आपके उदाहरण में)। मेरा पसंदीदा उदाहरण जहां यह समझ में आता है वह सापेक्ष और पूर्ण समन्वय है। जब आप absX = relX देखते हैं, तो आप स्पष्ट रूप से देख सकते हैं कि कुछ गलत हो सकता है। आप तदनुसार कार्यों का नाम भी दे सकते हैं: absX = absFromRel (relX, ऑफसेट);
VoidPointer

नोट: aszFred की इनिशियलाइज़ेशन संदिग्ध है (शाब्दिक स्ट्रिंग के लिए नॉन-कास्ट एक्सेस की पेशकश), और arrWilma का इनिशियलाइज़ेशन भी कंपाइल नहीं होगा। (आप शायद एक सूचक के बजाय अरिल्वल्मा को एक सरणी के रूप में घोषित करने का इरादा रखते हैं!) हालांकि कोई समस्या नहीं है, जैसा कि आपने लिखा है कि यह आपके सिर के शीर्ष से दूर है ... :-)
नील्स डीकेकर

उफ़, आप बिल्कुल सही कह रहे हैं। बच्चों, कि घर पर कोशिश मत करो। ऐसा करें: 'const char * aszFred = "Hi I a null-terminated string"; char arrililma [] = {'O', 'o', 'p', 's'};)
अल फलागन डेस

3

हमारी परियोजना ने हमेशा सदस्य डेटा के लिए उपसर्ग के रूप में "और" का उपयोग किया है, और स्थानीय लोगों के लिए कोई उपसर्ग के साथ "" उपसर्ग के रूप में। यह थोड़ा कैटेसी है, लेकिन इसे हमारे सिस्टम के शुरुआती डेवलपर्स द्वारा अपनाया गया था क्योंकि उन्होंने देखा कि इसे कुछ व्यावसायिक स्रोत पुस्तकालयों द्वारा एक कन्वेंशन के रूप में इस्तेमाल किया गया था जो हम उस समय उपयोग कर रहे थे (या तो XVT या RogueWave - शायद दोनों)। तो आपको कुछ इस तरह मिलेगा:

void
MyClass::SetName(const RWCString &theName)
{
   itsName = theName;
}

मैं उपसर्गों (और कोई अन्य नहीं - मैं हंगेरियन संकेतन से नफरत करता हूं) का बड़ा कारण यह है कि यह आपको कोड लिखने से परेशानी में आने से रोकता है, जहां आपको लगता है कि आप एक चर का जिक्र कर रहे हैं, लेकिन आप वास्तव में दूसरे चर का जिक्र कर रहे हैं स्थानीय दायरे में समान नाम के साथ। यह एक ही नाम की अवधारणा का प्रतिनिधित्व करने के लिए एक चर नामों के साथ आने की समस्या से भी बचता है, लेकिन ऊपर दिए गए उदाहरण की तरह अलग-अलग स्कोप के साथ। उस मामले में, आपको वैसे भी पैरामीटर "नाम" के लिए कुछ उपसर्ग या अलग नाम के साथ आना होगा - क्यों हर जगह लागू होने वाला एक सुसंगत नियम नहीं बनाया जाता है।

बस इसका उपयोग करना-> वास्तव में बहुत अच्छा नहीं है - हम अस्पष्टता को कम करने में रुचि नहीं रखते हैं क्योंकि हम कोडिंग त्रुटियों को कम करने में हैं, और स्थानीय रूप से पहचाने गए पहचानकर्ताओं के साथ नाम बदलना एक दर्द हो सकता है। दी गई, कुछ कंपाइलरों के पास उन मामलों के लिए चेतावनी देने का विकल्प हो सकता है, जहां आपने नाम को बड़े दायरे में रखा है, लेकिन अगर आप तीसरे पक्ष के पुस्तकालयों के एक बड़े समूह के साथ काम कर रहे हैं, तो वे चेतावनी एक उपद्रव बन सकती है। अप्रयुक्त चर के लिए नाम जो कभी-कभी अपने स्वयं के साथ टकराते हैं।

इसके / खुद के लिए - मैं ईमानदारी से अंडरस्कोर टाइप करना आसान समझता हूं (एक टच टाइपिस्ट के रूप में, जब भी संभव हो तो मैं अंडरस्कोर से बचता हूं - होम पंक्तियों को बहुत अधिक खींचना), और मुझे यह एक रहस्यमय अंडरस्कोर की तुलना में अधिक पठनीय लगता है।


यह मैंने कभी सुना है सबसे तेजी से सीखने की अवस्था के साथ सबसे सहज समाधान है। काश, बोली जाने वाली भाषाएं उन सभी को संभालने के लिए अधिक लचीली होतीं ताकि कोड में अस्पष्टता को हल करने के लिए हमें नई तकनीकों के साथ आने के बारे में सोचना न पड़े।
गनी ओजसन

2

मैं इसका उपयोग करता हूं क्योंकि वीसी ++ की इंटेलीसेंस यह नहीं बता सकती है कि कक्षा से बाहर पहुंचने पर निजी सदस्यों को कब दिखाना है। एकमात्र संकेत Intellisense सूची में फ़ील्ड आइकन पर थोड़ा "लॉक" प्रतीक है। यह सिर्फ निजी सदस्यों (क्षेत्रों) को पहचानना आसान बनाता है। साथ ही ईमानदार होने के लिए C # से एक आदत।

class Person {
   std::string m_Name;
public:
   std::string Name() { return m_Name; }
   void SetName(std::string name) { m_Name = name; }
};

int main() {
  Person *p = new Person();
  p->Name(); // valid
  p->m_Name; // invalid, compiler throws error. but intellisense doesn't know this..
  return 1;
}

2

मुझे लगता है कि, यदि आपको सदस्य फ़ंक्शन पैरामीटर और स्थानीय चर से वर्ग के सदस्यों को अलग करने के लिए उपसर्गों की आवश्यकता है, तो या तो फ़ंक्शन बहुत बड़ा है या चर बुरी तरह से नामित हैं। अगर यह स्क्रीन पर फिट नहीं होता है तो आप आसानी से देख सकते हैं कि क्या है, रिफ्लेक्टर।

यह देखते हुए कि वे अक्सर जहां वे उपयोग किए जाते हैं, वहां से दूर घोषित किए जाते हैं, मुझे लगता है कि वैश्विक स्थिरांक (और वैश्विक चर) के लिए नामकरण सम्मेलनों, हालांकि आईएमओ शायद ही कभी उन का उपयोग करने की आवश्यकता है) समझ में आता है। लेकिन अन्यथा, मैं बहुत जरूरत नहीं देखते हैं।

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


2
यह बहुत ही इस मुद्दे के बारे में महसूस करने पर मेरे विचार को दर्शाता है। उपसर्गों का सहारा लिए बिना कोड को पठनीय होना चाहिए। हो सकता है कि हम अधिक आधुनिक भाषाओं में इतना अधिक उपसर्ग उपयोग न करें क्योंकि उनके उपयोगकर्ता समुदायों ने पठनीयता को थोड़ा अधिक ग्रहण किया है जो आप कभी-कभी C ++ में देखते हैं। बेशक, सी ++ और पठनीय होना चाहिए। यह सिर्फ इतना है कि बहुत सारे अपठनीय C ++ वर्षों में लिखे गए हैं।
VoidPointer


1

यह स्मृति प्रबंधन के कारण सदस्य चर और स्थानीय चर के बीच अंतर करने के लिए उपयोगी है। मोटे तौर पर, ढेर-आवंटित सदस्य चर को विध्वंसक में नष्ट कर दिया जाना चाहिए, जबकि ढेर-आवंटित स्थानीय चर को उस दायरे में नष्ट किया जाना चाहिए। सदस्य चर के लिए एक नामकरण सम्मेलन लागू करने से सही स्मृति प्रबंधन की सुविधा मिलती है।


ऐसा कैसे? विध्वंसक के पास अन्य कार्यों में घोषित स्थानीय चर तक पहुंच नहीं है, इसलिए वहां भ्रम की कोई गुंजाइश नहीं है। इसके अलावा, ढेर-आवंटित स्थानीय चर मौजूद नहीं होने चाहिए । और ढेर-आवंटित सदस्य चर केवल RAII कक्षाओं के अंदर मौजूद होना चाहिए, बहुत ज्यादा।
jalf

"ढेर-आवंटित स्थानीय चर मौजूद नहीं होने चाहिए" थोड़ा मजबूत है। लेकिन अगर / जब आप उनका उपयोग करते हैं, तो यह सुनिश्चित करने के लिए कि यह उन्हें उचित ढंग से निपटाया जाता है, इसलिए सदस्य बनाम स्थानीय चर के लिए एक अनुशासित नामकरण सम्मेलन यह सुनिश्चित करने के साथ असीम रूप से सहायता करता है।
फ्रैंकस्टर

1

पूरा कोड सदस्य चर के लिए m_varname सुझाता है।

जबकि मैंने कभी नहीं सोचा था कि m_ नोटेशन उपयोगी है, मैं एक मानक बनाने में मैककोनेल की राय का वजन दूंगा।


2
तब तक नहीं जब तक वह नहीं समझाता कि अंडरस्कोर क्यों है। मैं उनकी "रैपिड डेवलपमेंट" पुस्तक का बहुत बड़ा प्रशंसक हूं, जिसे मैंने कई बार यहां सुझाया है, लेकिन "कोड कम्प्लीट" (जो मैं स्वीकार करता हूं कि मैं पहली बार बाहर आने के बाद पढ़ा नहीं था) से बहुत कम था।

1

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

केवल एक बार जब मैं उपसर्ग का उपयोग करता हूं तो हस्ताक्षर लाइन पर होगा। मैं _ के साथ एक विधि के लिए मापदंडों को उपसर्ग करूँगा ताकि मैं उनके चारों ओर रक्षात्मक रूप से कार्यक्रम कर सकूँ।


1

आपको इस तरह के उपसर्ग की आवश्यकता नहीं होनी चाहिए। यदि ऐसा उपसर्ग आपको कोई लाभ प्रदान करता है, तो आपकी कोडिंग शैली सामान्य रूप से फिक्सिंग की जरूरत है, और यह उपसर्ग नहीं है जो आपके कोड को स्पष्ट होने से रोक रहा है। विशिष्ट बुरे चर नामों में "अन्य" या "2" शामिल हैं। आप इसे ठीक नहीं करते हैं, इसे ठीक करने की आवश्यकता के साथ, आप डेवलपर को यह सोचने के लिए ठीक कर देते हैं कि उस फ़ंक्शन के संदर्भ में वह चर क्या कर रहा है। शायद उसका मतलब था रिमोटसाइड, या न्यूवैल्यू, या सेकंडटेस्टलिस्टर या उस दायरे में कुछ।

यह एक प्रभावी अभिवाद है जो अभी भी बहुत दूर प्रचारित है। अपने चरों को उपसर्ग करना बंद करें और उन्हें उचित नाम दें जिनकी स्पष्टता यह बताती है कि वे कितने समय से उपयोग कर रहे हैं। 5 लाइनों तक आप इसे भ्रम के बिना "i" कह सकते हैं; 50 लाइनों से परे आपको एक बहुत लंबे नाम की आवश्यकता है।


1

मुझे चर नाम पसंद हैं, जिसमें वे निहित मूल्यों को केवल एक अर्थ देते हैं, और नाम से बाहर घोषित / कार्यान्वित किए जाने के तरीके को छोड़ देते हैं। मैं जानना चाहता हूं कि मूल्य का मतलब क्या है, अवधि। हो सकता है कि मैंने औसतन अधिक मात्रा में रिफैक्टरिंग की हो, लेकिन मुझे पता चलता है कि नाम में कुछ कैसे लागू किया जाता है, यह बताता है कि रिफ्लेक्ट होने से ज्यादा थकाऊ होना चाहिए। उपसर्गों से संकेत मिलता है कि कहाँ या कैसे वस्तु सदस्य घोषित किए गए हैं, कार्यान्वयन विशिष्ट हैं।

color = Red;

ज्यादातर समय, मुझे परवाह नहीं है कि क्या लाल एक एनम, एक संरचना, या जो कुछ भी है, और यदि फ़ंक्शन इतना बड़ा है कि मुझे याद नहीं है कि क्या रंग स्थानीय रूप से घोषित किया गया था या वह एक सदस्य है, तो शायद इसे तोड़ने का समय है छोटी तार्किक इकाइयों में कार्य करता है।

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

ज्यादातर, मैं केवल कंस्ट्रक्टर और इनिशियलाइज़र में 'इस' का उपयोग करता हूँ।


0

मैं सदस्य चर के लिए m_ का उपयोग सिर्फ Intellisense और संबंधित IDE-कार्यक्षमता का लाभ लेने के लिए करता हूं। जब मैं एक वर्ग के कार्यान्वयन को कोडित कर रहा हूं तो मैं m_ टाइप कर सकता हूं और सभी m_ सदस्यों को एक साथ समूहीकृत किए गए कॉम्बोबॉक्स को देख सकता हूं।

लेकिन मैं m_ की समस्या के बिना रह सकता था, बिल्कुल। यह सिर्फ मेरी कार्यशैली है।


आप टाइप भी कर सकते हैंthis->
टोस्ट

0

ज्वाइंट स्ट्राइक फाइटर्स के अनुसार AIR VEHICLE C ++ CODING STANDARDS (दिसम्बर 2005):

एवी नियम 67

सार्वजनिक और संरक्षित डेटा का उपयोग केवल संरचना में किया जाना चाहिए - कक्षाएं नहीं। Rationale: एक वर्ग अपने डेटा तक पहुंच को नियंत्रित करके अपने आक्रमण को बनाए रखने में सक्षम है। हालाँकि, एक वर्ग अपने सदस्यों तक पहुंच को नियंत्रित नहीं कर सकता है यदि वे सदस्य गैर-निजी हैं। इसलिए एक वर्ग का सभी डेटा निजी होना चाहिए।

इस प्रकार, "एम" उपसर्ग अप्रयुक्त हो जाता है क्योंकि सभी डेटा निजी होना चाहिए।

लेकिन एक सूचक के पहले p उपसर्ग का उपयोग करना एक अच्छी आदत है क्योंकि यह एक खतरनाक चर है।


0

उन सम्मेलनों में से कई परिष्कृत संपादकों के बिना एक समय से हैं। मैं एक उचित आईडीई का उपयोग करने की सलाह दूंगा जो आपको हर प्रकार के चर को रंग देने की अनुमति देता है। रंग किसी भी उपसर्ग की तुलना में अधिक आसान है।

यदि आपको एक चर पर और भी अधिक विवरण प्राप्त करने की आवश्यकता है तो किसी भी आधुनिक आईडीई को उस पर कैरेट या कर्सर ले जाकर आपको दिखाने में सक्षम होना चाहिए। और अगर आप एक चर का गलत तरीके से उपयोग करते हैं (उदाहरण के लिए ऑपरेटर के साथ एक संकेतक) तो आपको एक त्रुटि मिलेगी, वैसे भी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.