2009-12-25 3 views
11

सटीक डुप्लिकेट:Do you prefer explicit namespaces or ‘using’ in C++?स्टैंडर्ड सम्मेलन

इनमें से कौन किसी भी नाम स्थान का उपयोग कर के लिए एक पसंदीदा सम्मेलन है?

using namespace std; 

या

using std::cin; 
using std::cout; 

या

प्रकार्य को बुलाने और जब कोड में आवश्यक?

std::cout<<"Hello World!"<<std::endl; 
+5

दूसरे सम्मेलन का उपयोग न करें, आप अपनी सैनिटी खो देंगे। –

+7

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

+1

संदर्भ के आधार पर दूसरा या तीसरा। पहला व्यक्ति केवल "हैलो वर्ल्ड" ट्यूटोरियल या त्वरित डेमो के लिए उपयोग किया जाना चाहिए। –

उत्तर

14

एक बहुत अच्छी व्याख्या here दिया जाता है।

पहली शैली यानी नेमस्पेस का उपयोग करते हुए जो भी नामस्थान के पूरे उद्देश्य को हरा देता है। छोटे कोड स्निपेट को छोड़कर आपको इसे कभी भी इस्तेमाल नहीं करना चाहिए। (मैं इसका उपयोग वहां नहीं करता हूं!: डी)

दूसरा एक तरीका भी वर्बोज़ है। अप्रायौगिक।

मुझे व्यक्तिगत रूप से तीसरी शैली पसंद है यानी पूरी तरह से योग्य नाम टाइप करना (उदा। Std :: cout)।

याद रखें, कोड & लिखा गया है उससे अधिक बार लिखा जाता है आईएमओ आपके कोड को और अधिक पठनीय बनाता है।

+6

प्रोग्रामिंग में किसी भी अवधारणा का उद्देश्य प्रोग्रामर के लिए जीवन को आसान बनाना है। यदि आप मानक लाइब्रेरी का भारी उपयोग कर रहे हैं, तो 'कुछ का उपयोग' करने से आपका कोड अधिक संक्षिप्त हो सकता है। 'Std :: स्ट्रिंग का उपयोग कैसे किया जा रहा है; एक स्ट्रिंग; स्ट्रिंग बी; स्ट्रिंग सी; 'std :: string a की तुलना में स्ट्रिंग डी' अधिक verbose; std :: स्ट्रिंग बी; std :: स्ट्रिंग सी; std :: स्ट्रिंग डी; '? यदि आपको इसका बहुत उपयोग करना है, तो पूरी तरह से योग्य नाम बोझिल हो जाता है। और गंभीरता से, जो पहले से ही 'std :: string' है, अपने स्वयं के' स्ट्रिंग 'वर्ग को हाथ से घुमाने वाला कौन है? यदि आप 'स्ट्रिंग x' 9 5% समय कहते हैं तो यह 'std :: string' है और हर कोई इसे जानता है। –

+0

यह एक अपवाद है। क्या होगा यदि आप "std :: count का उपयोग करके" कहते हैं और बाद में एक ही नाम के साथ फ़ंक्शन या चर को परिभाषित करने की आवश्यकता है? – missingfaktor

+6

असहमत: मुझे स्रोत फ़ाइल में 'नेमस्पेस std;' का उपयोग करने में कोई समस्या नहीं दिखाई दे रही है। लेकिन शीर्ष लेख फ़ाइल में # 1 या # 2 का उपयोग न करें। – rlbond

-4

जो भी आप चाहें। वास्तव में, इससे कोई फर्क नहीं पड़ता। हालांकि, ज्यादातर कोड-स्निपेट का उपयोग

using namespace std; 
+2

... और जो नामस्थान के पूरे उद्देश्य को हरा देता है। – missingfaktor

+3

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

+2

स्निपेट्स! = वास्तविक कोड – rlbond

12

यह कई बार कहा गया है से पहले, लेकिन मेरे अतः खोज फू पल के लिए मुझे अकेला छोड़ दिया है। मूल रूप से:

  • कभी नहीं एक हेडर फाइल – ऐसा करने से आपके कोड को दूषित और कीड़े नीचे ट्रैक करने के लिए कड़ी मेहनत के सभी प्रकार का परिचय देंगे में किसी भी तरह की एक का उपयोग कर के निर्देश डाल दिया।

  • एक कार्यान्वयन (.cpp) फ़ाइल में using std::string की तरह एक उपयोग घोषणा पसंद करें, जो इस तरह के प्रकार का भारी उपयोग करता है।

  • अंतिम उपाय के रूप में, using namespace std का उपयोग करें, लेकिन केवल कार्यान्वयन फ़ाइलों में – मैं सुविधा के लिए SO पर संकलित कोड के पदों में इसका उपयोग करता हूं।

+0

छोटी कार्यान्वयन फ़ाइलों के लिए मुझे नेमस्पेस का उपयोग करने में समस्या दिखाई नहीं दे रही है। मुझे लगता है कि अगर आपके पास एक विशाल वर्ग था, तो आप समस्याओं में भाग ले सकते थे। – Steve

+2

"छोटा" क्या है? मैं विशाल वर्ग नहीं लिखता, लेकिन मैं अपने सिर में सी ++ मानक पुस्तकालय में हर नाम नहीं रखता हूं। जिन नामों का मैं आम तौर पर उपयोग करता हूं उन्हें स्पष्ट रूप से निर्दिष्ट करता हूं (और बहुत ही मुश्किल, डीबग करने में बहुत मुश्किल) समस्याएं। –

+0

हालांकि एडीएल मानक कार्यों के नामों के साथ आपके संदर्भ को प्रदूषित करने से बचने के लिए आपकी सर्वोत्तम योजनाओं के आसपास काम कर सकता है।'# शामिल करें # शामिल int मुख्य() {std :: वेक्टर foo; std :: वेक्टर बार; कॉपी (foo.begin(), foo.end(), bar.begin()); } '। यदि आप किसी अन्य चीज़ के लिए "प्रतिलिपि" नाम का उपयोग करने की योजना बना रहे थे, तो सबसे अच्छा यह सुनिश्चित करें कि आप कभी भी अपने संस्करण को गलती से कॉल न करें जब एडीएल द्वारा अधिभारित अधिभार, या इसके विपरीत। –

1

यह शैली का विषय है, लेकिन एक बात के लिए: आपको कभी भी वैश्विक क्षेत्र में नामस्थान आयात नहीं करना चाहिए। उदा .:

#include <iostream> 
using namespace std; // Pollution! 

int main() 
{ 
    .... 
} 

आप आयात करना नाम स्थान अभी गुंजाइश है जहाँ आप काम कर रहे हैं करने के लिए आयात करना चाहते हैं:

#include <iostream> 

int main() 
{ 
    using namespace std; // Good! 
    .... 
} 
+0

वास्तव में नहीं। यह आपके कार्यक्रम पर निर्भर करता है (यह कितना बड़ा है, यह मानक पुस्तकालय, आदि का कितना उपयोग करता है)। –

+2

@ ब्रायन क्या आपका मतलब है कि वैश्विक दायरे में नामस्थान आयात करना ठीक है ?! – AraK

+1

मैं कहूंगा कि यह ठीक है। हेडर फ़ाइल में नहीं, लेकिन यह ठीक है। इन चीजों के बारे में डरावना होना बुरा है, और ज्यादातर मामलों में यह भयानक नहीं है। उदाहरण के लिए, यदि मैं किसी स्रोत फ़ाइल में ग्राफ़ लाइब्रेरी का उपयोग करने जा रहा हूं, तो 'नेमस्पेस MyGraphLibrary का उपयोग करके' कहने का अधिकार है। दुनिया विस्फोट नहीं करेगा, आपका कोड ठीक रहेगा। यदि आप इसके बारे में सावधान हैं तो यह प्रदूषण नहीं है। – rlbond

8

यह एक ही विषय पर मैंने लिखा एक और उत्तर का एक संशोधित संस्करण है।इन सवालों में से पर्याप्त और शायद मैं एक निश्चित पद के साथ समाप्त हो जाऊंगा;)

प्रमुख मुद्दा नाम विवाद है, यदि आपके पास आपके कोड में कोउट नामक एक चर है और आप using namespace std; हैं तो यह अस्पष्ट होगा तुम्हारा मतलब है। यह सिर्फ cout नहीं है। count, reverse और equal भी शामिल किए जाएंगे, जो सभी आम पहचानकर्ता हैं।

कंपाइलर को सभी समस्याओं को अस्वीकार करना, यह आपके कोड को पढ़ने वाले किसी भी व्यक्ति के लिए भी एक समस्या है। उन अतिरिक्त 5 वर्णों से यह सुनिश्चित होता है कि आपका कोड बनाए रखने वाला अगला व्यक्ति वास्तव में आपका मतलब बताता है।


यह भी ध्यान देने योग्य है कि आप कभी नहीं रखना चाहिए एक हेडर फाइल में

using namespace std; 

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

मामलों के बहुमत में यह बहुत की तरह

using std::swap 

चीजों का उपयोग करने के रूप में अगर वहाँ स्वैप की एक विशेष संस्करण है, संकलक का उपयोग करेगा फायदेमंद है, अन्यथा यह std::swap पर प्रारंभ कर देगा। यदि आप std::swap पर कॉल करते हैं, तो आप हमेशा मूल संस्करण का उपयोग करते हैं, जो विशेष संस्करण को कॉल नहीं करेगा (भले ही यह मौजूद है)।

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


सारांश में,

  • हमेशा using std::swap प्रचार की वजह से हर हालत में एक शीर्षक में std::swap() से अधिक

  • बचें using namespace std पसंद करते हैं, कार्यान्वयन फ़ाइलों में इसका उपयोग करने से बचने की कोशिश।

  • प्रत्येक फ़ाइल के शीर्ष पर हजारों using std::foo होने का कोई तरीका नहीं है। आमतौर पर कक्षाओं का उपयोग करने के लिए इसका उपयोग करें।

बाकी सब कुछ राय है।

+0

+1: 'std :: swap' उपयोग पर दिलचस्प विचार जो मैं व्यक्तिगत रूप से असहमत हूं। हालांकि, इस विषय पर 2000 (http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/b396fedad7dcdc81) से यूएसनेट पोस्टिंग पढ़ने के बाद, मुझे इसमें अधिक रूचि है। निजी तौर पर, मैं _use 'std :: swap' का पक्ष लेता हूं और इसे_ शिविर का विशेषज्ञ करता हूं। –

3

मैं व्यक्तिगत रूप से तीसरा विकल्प पसंद करता हूं।बस इस पर एक नजर है:

namespace A { int a=0; } 
namespace B { int a=0; } 

और आप के रूप में उपयोग:

using namespace A; 
using namespace B; 
using namespace std; 

cout<<a<<endl; //error here! 

इसके बजाय अगर आप सिर्फ कह सकते हैं,

std::cout<<B::a<<std::endl; //No problem, more readable 

हालांकि यह थोड़ा और समय लग सकता है कोड टाइप करें, दूसरा और तीसरा विकल्प अधिक (प्रकार का) पसंदीदा है।

+3

उनमें से कोई भी कम या ज्यादा पठनीय नहीं है क्योंकि आप अपने प्रतीकों के चारों ओर किसी भी रिक्त स्थान का उपयोग नहीं करते हैं। एसओ पर कोड स्निपेट अभी भी __nice__ देख सकते हैं। अंतिम वाक्य के लिए –

1

मैं बस यह इंगित करना चाहता हूं कि using namespace foo स्कॉप्ड है। उदाहरण:

#include <iostream> 
#include <vector> 
//... 
for (int i=0; i<10; ++i) 
{ 
    using namespace std; 
    cout << i << endl; 
} 
vector v; // won't compile 

जब उपयोग सावधानी से किया, using namespace std उपयोगी और एक ही समय में हानिरहित हो सकता है।

1

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

याद रखने के लिए एक अच्छा आदेश: सबसे महत्वपूर्ण व्यक्ति वह क्लाइंट है जो प्रोग्राम का उपयोग करता है; दूसरी सबसे महत्वपूर्ण अन्य कोडर हैं जो या तो आपके कोड से सीखने या सीखने की कोशिश कर रहे हैं; आप कम से कम महत्वपूर्ण है। :-)

+0

+1! :) – missingfaktor

0

नामस्थान स्थिर होने पर पूरी तरह से योग्य नाम लिखने की सिफारिश करना एक बात है, जहां std :: केवल 5 अतिरिक्त वर्ण जोड़ता है। जब नामस्थान ढेर यह एक 'पूरे nother मुद्दा है, और आप की तरह कुछ लिखने के साथ सामना कर रहे हैं:

if (NumberOfInstances > 0 && (code_type == MyNamespace::MyLongButMeaningfulClassName::EnumDefinedWithinClass::CODE_GREEN || 
           code_type == MyNamespace::MyLongButMeaningfulClassName::EnumDefinedWithinClass::CODE_YELLOW)) { 

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