"नाम स्थान का उपयोग" प्रदूषण क्या है?


15

मैं गूगल कोडिंग गाइड को देख रहा था [यहाँ] और वे यह सलाह नहीं देते कि कोई इसका इस्तेमाल करे using namespaceया namespace::function- अगर मैंने इसका गलत मतलब नहीं निकाला।

क्या यह भी लागू होता है std? cout<<इसके बिना काम नहीं होता। यह पुस्तक , वही सुझाती है। तो मैं कैसे या cout<<बिना उपयोग के बारे में कैसे जाना है ?using namespace std;std::cout<<

अनुशंसित तरीका क्या है? std::cout<<? अधिकांश c ++ टेक्स्ट बुक्स से शुरुआती लोगों को सिखाया जाता है कि using namespace std;क्या वे खराब कोडिंग प्रैक्टिस का प्रचार कर रहे हैं?

जवाबों:


18

जैसा कि मैंने Google मानक पढ़ा है, आप using namespace foo;कहीं भी निर्देश का उपयोग नहीं कर सकते । यह निर्देश नेमस्पेस में घोषित सभी चीजों को लाता है और टकराव और अप्रत्याशित व्यवहार का एक सामान्य कारण है। अन्य लोगों ने एक बहुत ही सामान्य का हवाला दिया है: आपके पास अपनी अधिकतम या न्यूनतम विधि कहीं और है और यह एक src फ़ाइल में टकराती है, जहाँ कोई आपकी विधि के साथ एक हेडर शामिल करता है और फिर कहता हैusing namespace std;

कुछ स्थानों पर, इसका उपयोग करने की घोषणा करने की अनुमति है, जो फॉर्म का है using ::foo::bar;

लोग अपने कोड में निर्देशों का उपयोग करना पसंद करते हैं क्योंकि यह बहुत टाइपिंग बचाता है, लेकिन यह जोखिम के साथ आता है। यदि आपके पास बहुत सारे cout कथनों वाली फाइल है, तो मैं समझ सकता हूँ कि std :: cout को एक सौ बार टाइप करना नहीं है, लेकिन आप बस :: std :: cout का उपयोग करके कह सकते हैं। मैं इन्हें चर घोषणाओं की तरह मानता हूं: जहां जरूरत होती है, वहां इनकी गुंजाइश होती है। यदि आउटपुट लिखने के लिए 10 की फ़ाइल में किसी एक फ़ंक्शन को सबसे ऊपर की ओर जाने की जरूरत नहीं है, तो इसे उस फ़ंक्शन में रखें, जो वास्तविक आउटपुट कर रहा है।

#include <ostream>
//using namespace std; // NO!
//using ::std::cout;   // less bad than using namespace, but I prefer to scope it

int main(int argc, char** argv)
{
   int rc = do_some_stuff(argc, argv);
   using ::std::endl;
   if (rc) { // print the success report
      using ::std::cout;
      cout << "The test run completed. The return code was " << rc << '.' << endl;
    } else {
      using ::std::cerr;
      cerr << "Unable to complete the test run." << endl;
    }
    return 0 == rc;
}

यह सिर्फ उत्पादन कर रही लाइनों की एक जोड़ी के साथ थोड़ा चरम है, लेकिन आप विचार प्राप्त करते हैं।

टाइपिंग को कम से कम करने के लिए एक और चीज है, वह है अन्य प्रकार या उपनाम। मुझे std नहीं मिल रहा है: जो कुछ भी है कि बुरा है, लेकिन हमारे पास कई दर्जन मॉड्यूल के साथ स्रोत का एक बड़ा सेट है और कभी-कभी हमें कोड को लिखना पड़ता है console_gui::command_window::append("text")। यह थोड़ी देर के बाद थकाऊ हो जाता है और बहुत लंबी लाइनों का कारण बनता है। मैं सब कुछ की तरह हूँ

typedef console_gui::command_window cw;
cw::append("text");

जब तक एलियंस स्थानीय दायरे में होते हैं और कोड को पठनीय बनाने के लिए पर्याप्त संदर्भ रखते हैं।


1
धन्यवाद! यह वास्तव में मददगार है। आपने न केवल समझाया कि यह अच्छे उदाहरणों के साथ बुरा क्यों है, बल्कि अच्छे उदाहरणों के साथ समाधान भी बताया है। :-)
भगवान लोह।

1
BTW: std::endlपर स्पष्ट फ्लश के लिए stdout/ stderrका उपयोग आम तौर पर बहुत ही कम होता है, उन धाराओं को stdout/ stderrवैसे भी बांध दिया जाता है। यह चीजों को थोड़ा धीमा कर देता है।
डेडुप्लिकेटर

8

ऐसा इसलिए है क्योंकि: 1) यह नामस्थानों के पूरे उद्देश्य को हरा देता है, जो कि नाम टकराव को कम करना है; 2) यह वैश्विक नामस्थान को उपलब्ध निर्देश के साथ निर्दिष्ट पूरे नामस्थान को उपलब्ध कराता है।

उदाहरण के लिए, यदि आप अपने स्वयं के अधिकतम () फ़ंक्शन को शामिल और परिभाषित करते हैं, तो यह std :: max () के साथ टकराएगा।

http://en.cppreference.com/w/cpp/algorithm/max

प्राथमिकता std :: member_you_wish_to_use का उपयोग करना है क्योंकि यह स्पष्ट रूप से बताता है कि किस नामस्थान का उपयोग करना है।


मुझे लगता है इसका मतलब है कि मुझे std::max()नाम स्थान उपसर्ग के साथ उपयोग करना चाहिए । या मैं गलत हूँ?
भगवान लोह।

3
इसका मतलब है कि यदि आप "नाम स्थान std का उपयोग कर रहे हैं;" यदि आप अपने स्वयं के अधिकतम कार्य को परिभाषित करते हैं, (या किसी अन्य नाम पहले से ही std नाम स्थान में परिभाषित करते हैं), तो आपको त्रुटियां मिलेंगी
Chewy Gumball

1
इसका सिर्फ यह अर्थ है कि आपको usingनिर्देशों के साथ सावधान रहना चाहिए क्योंकि इस मामले में यह आपके अधिकतम () फ़ंक्शन को तोड़ देगा यदि आपने एक को परिभाषित किया था और "एल्गोरिथ्म> शामिल किया था। यह एक साधारण मामला है लेकिन आप कभी नहीं जानते कि आप क्या तोड़ सकते हैं। आपको पूरी लाइब्रेरी को जानना होगा कि आपने इसे तोड़ा नहीं है, लेकिन आप यह नहीं जान सकते कि भविष्य में आपका कोड (यानी नाम टकराव) टूट जाएगा या नहीं।
ApplePie

6

आपके द्वारा प्रदत्त लिंक का हवाला देते हुए:

आप एक .cc फ़ाइल में, और फ़ंक्शंस, विधियों या कक्षाओं में .h फ़ाइलों में कहीं भी उपयोग करने की घोषणा कर सकते हैं।

// .cc फ़ाइलों में ठीक है।

// .h फाइलों में एक फंक्शन, मेथड या क्लास में होना चाहिए।

का उपयोग कर :: फू :: बार;

Google शैली आपको वैश्विक संदर्भ में नाम स्थान का उपयोग करने से मना करती है, लेकिन स्थानीय लोगों में ऐसा करने की अनुमति देती है।

हर जगह जहां घोषणा का उपयोग केवल कोड के सीमित और स्पष्ट रूप से दिखाई देने वाले हिस्से को प्रभावित करता है, यह पूरी तरह से स्वीकार्य है।

जब आप वैश्विक संदर्भ को प्रदूषित करते हैं, तो असंबंधित कोड प्रभावित होता है (आपके हेडर का उपयोग करके अस्पष्टता से)। जब आप स्थानीय संदर्भ में ऐसा करते हैं तो कुछ नहीं होता है।


हमारे पास समान मानक हैं। हमारे कुछ लोग स्थानीय रूप से एक लंबा नाम स्थान टाइप करेंगे। उदाहरण के लिए टाइप्डिफ मूर्ख :: बैरिकेड एफबी; fb :: पेय d;
माइकल मैथ्यूज

1

वे अनुशंसा नहीं करते हैं कि कोई नामस्थान का उपयोग करने के लिए ornamespace का उपयोग करें: function` - अगर मैंने इसका गलत अर्थ नहीं निकाला।

तुमने किया। अव्यवस्था केवल using namespaceनिर्देश पर लागू होती है (जिसे आमतौर पर के रूप में संदर्भित किया जाता है abusing namespace, पूरी तरह से विनोदी नहीं)। यह दृढ़ता से पसंद किया जाता है कि आप किसी फ़ंक्शन या ऑब्जेक्ट के पूरी तरह से योग्य नाम का उपयोग करते हैं, जैसे कि std::cout


1

हालाँकि इस प्रश्न के पहले से ही उपयोगी उत्तर हैं, एक विस्तार बहुत कम लगता है।

अधिकांश प्रोग्रामर पहले तो usingकीवर्ड और namespaceउपयोग के विवरणों के बारे में थोड़ा भ्रमित होते हैं , भले ही वे संदर्भ को देखकर इसे सीखने की कोशिश करें, क्योंकि घोषणा और निर्देश कुछ हद तक समतुल्य है, दोनों अपेक्षाकृत सार शब्द d से शुरू होते हैं ।

नामस्थान के भीतर पहचानकर्ता नाम स्थान का नामकरण करके स्पष्ट रूप से सुलभ हैं:

myNamespace::myIdent

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

... निश्चित रूप से घोषणा का उपयोग करने के बीच एक अंतर है

using myNamespace::myIdent; // make myIdent an alias of myNamespace::myIdent

और निर्देशन का उपयोग करना

using myNamespace; // make all identifiers of myNamespace directly accessible

यदि विशाल स्कोप में उपयोग किया जाता है, तो उत्तरार्द्ध बहुत अधिक भ्रम की ओर जाता है ।


1

हेयर यू गो:

#include <iostream>

int main()
{
    std::endl(std::operator<<(std::cout, "Hello world!"));
}

इसे इस तरह से लिखने से, हम निर्देशों और घोषणाओं का उपयोग करने के साथ-साथ एडीएल त्रुटि से बचते हैं।

यह एक व्यंग्यात्मक उत्तर है। :-D

मैं इस पर Google पर हर्ब सटर के साथ हूं। C ++ कोडिंग मानकों से:

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

आप संभावित नामस्थान संघर्षों के बारे में जुनूनी हो सकते हैं जो शायद कभी प्रकट नहीं होंगे और शायद इस तरह के एक खगोलीय दुर्लभ घटना को ठीक से usingनिर्देशन से बचने और स्पष्ट रूप से प्रत्येक और हर चीज जिसे आप उपयोग करते हैं (ऑपरेटरों के लिए) usingघोषणाओं से निर्दिष्ट करके , या बस आगे बढ़ो और शुरू करो using namespace std। मैं उत्पादकता के दृष्टिकोण से उत्तरार्द्ध की सिफारिश करता हूं।

ज्यादातर सी ++ टेक्स्ट बुक्स नामस्थान एसटीडी का उपयोग करने के साथ शुरुआती सिखाती हैं; क्या वे खराब कोडिंग अभ्यास का प्रचार कर रहे हैं?

यदि आप मुझसे पूछते हैं तो विपरीत है, और मेरा मानना ​​है कि सटर सहमत हैं।

अब, मेरे करियर के दौरान, मुझे usingLOC के लाखों लोगों के दसियों तक के कोडबेस में निर्देशों के प्रत्यक्ष परिणाम के रूप में कुल 3 नामस्थान संघर्षों का सामना करना पड़ा है । हालांकि, सभी 3 मामलों में, वे स्रोत फ़ाइलों में थे, जो विरासत कोड की 50,000 से अधिक पंक्तियों में फैली हुई थीं, मूल रूप से सी में लिखी गई थीं और फिर सी ++ में कमी की गई थीं, एक दर्जन अलग-अलग पुस्तकालयों के हेडर सहित असमान कार्यों की एक विशाल उदार सूची का प्रदर्शन किया और किया। #includesउस पृष्ठ की एक पृष्ठ पर एक महाकाव्य सूची । महाकाव्य गड़बड़ी के बावजूद, वे ठीक करने में बहुत मुश्किल नहीं थे क्योंकि वे OSX (एक ओएस जहां कोड बनाने में विफल रहे थे) पर त्रुटियों का कारण बना, रनटाइम बग नहीं। इस बुरे सपने को अपने कोड को व्यवस्थित न करें और आपको ठीक होना चाहिए।

उस ने कहा, हेडर फ़ाइलों में निर्देशों और घोषणाओं दोनों से बचें using। वह सिर्फ सादा है। लेकिन स्रोत फ़ाइलों के लिए, और विशेष रूप से उन लोगों के लिए, जिनके पास #includeनिर्देशों से भरा एक पूरा पृष्ठ नहीं है , मैं कहूंगा कि यदि आप Google के लिए काम नहीं कर रहे हैं तो यह पसीना नहीं बहाएगा।

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