2013-01-03 11 views
6

मैं सी ++ में namespace और using के बारे में कुछ सोच रहा हूं मूल रूप से मैं अंतरों को जानना चाहता हूं और सर्वोत्तम तरीके से इसका उपयोग कैसे करना चाहता हूं।सी ++ नाम संकल्प

मैं इसे देखना वहाँ के रूप में (कम से कम) तीन एक वर्ग के नाम को हल करने के कई तरीके हैं और मुझे यकीन है कि कैसे उन के बीच चयन करने के लिए नहीं कर रहा हूँ:

  1. using namespace <namespace>
  2. using <namespace>::<what_to_use>
  3. <namespace>::<what_to_use> <use_it>

मैं फायदे जानना चाहता हूं विशेष रूप से यदि एक या दूसरे तरीके से प्रदर्शन शामिल है, तो यह केवल वाक्य रचनात्मक है और मैं हूं वरीयता का एटर या यदि अन्य चीजें हैं तो मैंने इसके बारे में नहीं सोचा है।

+1

यह रनटाइम प्रदर्शन से संबंधित नहीं है। –

+1

मुझे बताया गया था कि जब मैं कॉलेज में था, तो 'नेमस्पेस std का उपयोग करके' नामस्थान में सभी नामस्थान रखने के अलावा, एक सुरक्षा गड़बड़ी भी थी। –

+1

1. आपके द्वारा वर्णित कारण के लिए निराश किया गया है 2. एडीएल की सहायता से दूसरों द्वारा प्रदान किए गए कार्यों का उपयोग करने में आपकी सहायता करता है ('std :: swap' देखें, हालांकि एक उत्तर आपको बेहतर तरीके से समझाएं) 3। मैं सबसे ज्यादा पसंद करता हूं लेकिन यह स्वाद का विषय है और यदि आप मेरे स्थान पर 'std ::' को देखने के शौकीन नहीं हैं तो बोझिल हो सकता है। लेकिन उनमें से कोई भी प्रदर्शन अंतर नहीं है, वे सिर्फ नाम संकल्प के बारे में हैं और * "वास्तविक कोड में संकलित" नहीं मिलता है *। –

उत्तर

5

पहले एक using namespace directive, यह आपके वर्तमान नाम स्थान में निर्दिष्ट नाम स्थान से सभी प्रतीक नाम लाता है, आप की जरूरत/उन्हें इस्तेमाल चाहे है। निश्चित रूप से अवांछित।

दूसरा using namespace declaration है। यह केवल आपके वर्तमान नामस्थान में निर्दिष्ट प्रतीक नाम लाता है। लाभ यह है कि आपको हर बार पूरी तरह से योग्य नाम टाइप करने की आवश्यकता नहीं है।

तीसरा एक प्रतीक के पूर्ण योग्य नाम है। नुकसान यह है कि आप प्रतीक का उपयोग करते हुए हर जगह पूरी तरह से योग्य नाम टाइप करना होगा।

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

संपादित करें:
@Jerry के रूप में बताते हैं, ADL (तर्क निर्भर देखने) के साथ संयोजन में घोषणा का उपयोग कर अवांछनीय प्रभाव हो सकता है।

Detailed explanation on how Koenig lookup works with namespaces and why its a good thing?

धारा के तहत

,
क्यों कोएनिग एल्गोरिथ्म की आलोचना:
आप अपने जवाब में से एक में एक विस्तृत विवरण मिल सकती है?

+0

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

+1

@qrikko: आमतौर पर संगठन के कोडिंग मानकों द्वारा जाना जाता है। अन्यथा यह एक व्यक्तिगत पसंद है। एक बार चुनाव करने के बाद स्थिरता रखना महत्वपूर्ण है। –

+0

@qrikko: दुर्भाग्यवश, यदि आप मेरे उत्तर के माध्यम से पढ़ते हैं, तो आपको एहसास होगा कि 1) आप जितना सुरक्षित मानते हैं उतना सुरक्षित नहीं हैं, और 2) दावा करने वाले सभी उत्तरों प्रदर्शन पर कोई प्रभाव नहीं डाल सकते हैं (परोक्ष रूप से) कम से कम संभावित रूप से गलत। वे सही हैं कि जिस फ़ॉर्म में आप नाम निर्दिष्ट करते हैं, वह * सीधे * प्रदर्शन को प्रभावित नहीं करता है, लेकिन अभी भी गलत कहने के लिए गलत है (या यहां तक ​​कि यह भी इंगित करता है) कि प्रदर्शन को प्रभावित नहीं किया जा सकता है। –

0

मुख्य कारण यह है कि यह अस्पष्टता (दोनों संकलक के लिए और मानव पाठक के लिए) का नेतृत्व कर सकेगी और यह भी मंदी संकलन खुद कर सकते हैं (लेकिन है कि पहली बात यह है के रूप में है कि बड़ी समस्या नहीं है)

2

कोई प्रदर्शन नहीं है लाभ या जुर्माना जो भी हो। संकलन समय पर सभी कॉल और चर हल हो जाते हैं।

तीनों के बीच चुनाव कुछ हद तक व्यक्तिपरक है। हां, using namespace <ns>; कभी-कभी वैश्विक नामस्थान प्रदूषण के लिए फंस गया है, लेकिन मुझे लगता है कि छोटी फ़ाइलों के लिए उपयोग करना सुरक्षित है।

मैं परीक्षण उद्देश्यों के लिए दूसरे का उपयोग करता हूं जहां मुझे संघर्ष की उम्मीद है, लेकिन मैं इसे बाद में हटा दूंगा। क्योंकि आप शीर्ष पर एक using std::vector; है

vector<std::string> x; 

, लेकिन नहीं एक using std::string;: यह मेसियर प्राप्त कर सकते हैं क्योंकि आप दोनों योग्य और अन-योग्य नामों में से संयोजनों के साथ खत्म हो सकता है।

मैं तीसरा preffer।

1

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

using namespace std (या उस मामले के लिए कोई अन्य नामस्थान) निश्चित रूप से हेडर फ़ाइलों में से बचा जाना चाहिए, जिसे कहीं भी शामिल किया जा सकता है और उनमें प्रतीकों को पेश करने से अस्पष्टताएं हो सकती हैं।

आम तौर पर, नाम संघर्ष से बचने के लिए नामस्थान मौजूद हैं और using namespace इस उद्देश्य को नष्ट कर देता है। तो using the_namespace::some_id, कम डिग्री के लिए करता है। वहाँ अपने प्रश्न का कोई निश्चित जवाब है, लेकिन मैं आम तौर पर इन नियमों का पालन:

  1. कभी एक हेडर फाइल में using namespace डाल दिया।
  2. using namespace और using से बचें, जब तक कि यह टाइपिंग की जबरदस्त मात्रा को बचा सके। यदि आवश्यक हो तो नामस्थान उपनाम का उपयोग करें (यानी, namespace abbrv = some_really::long_and::nested_namespace;)।
  3. using के दायरे को सीमित करने का प्रयास करें: आप इसे फ़ंक्शंस और ब्लॉक के साथ-साथ नेमस्पेस स्कोप में भी डाल सकते हैं। यही है, अगर आपके पास अपनी .cpp फ़ाइल में लॉगिंग फ़ंक्शन है, तो फ़ाइल स्कोप में नहीं, using std::cout; और using std::endl; (या जो भी आप उपयोग कर रहे हैं) को फ़ंक्शन बॉडी में रखें।
4

वहाँ एक (वैसे, कुछ हद तक असामान्य) स्थिति है जिसमें प्रपत्र तुम सच में प्रयोग कर एक फर्क कर सकते हैं है, और प्रपत्र आप उपयोग करना चाहते हैंusing namespace foo है, और यह सबसे अधिक std नाम स्थान पर लागू की गई (यानी, जहां using namespace std; लिखें।

सबसे स्पष्ट उदाहरण है कि आप एक उपयोगकर्ता-निर्धारित प्रकार के लिए एक तरह से लिख रहे हैं है। यह संभव है कि यह एक प्रकार है जो के लिए उपयोगकर्ता भी परिभाषित किया गया है को लागू किया जाएगा उनके स्वयं swap

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

इस के आसपास पाने के लिए आपको करना कुछ की तरह:

using namespace std; 

template <class Iter> 
void my_sort(Iter first, Iter last) { 
    // ... 
    if (*last < *first) 
     swap(*first, *last); 
} 

इस प्रकार के लिए विशेष रूप स्वैप मिलेगा तुलना की जा रही (यानी, एक swap उस प्रकार के रूप में ही नाम स्थान में परिभाषित), अगर वहाँ है एक (तर्क निर्भर लुकअप के माध्यम से), और std::swap यदि किसी प्रकार के लिए परिभाषित नहीं किया गया है (using namespace std; के माध्यम से)।

इसका प्रदर्शन पर असर पड़ सकता है - अगर उन्होंने विशेष रूप से अपने प्रकार के लिए एक स्वैप लिखा है, तो आप आमतौर पर उम्मीद कर सकते हैं कि ऐसा करने से, वे बेहतर प्रदर्शन प्रदान कर सकते हैं। इसका मतलब है कि std::swap स्पष्ट रूप से निर्दिष्ट कर सकता है, लेकिन संभवतः कम प्रदर्शन का कारण बन जाएगा।

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

अन्य बार जब मैं घोषणाओं/निर्देशों का उपयोग करता हूं तो उपयोगी होता है जब नामस्थान वास्तव में गहराई से घोंसला प्राप्त करते हैं। बूस्ट (एक स्पष्ट उदाहरण के लिए) में कुछ नाम हैं जो सुविधाजनक उपयोग के लिए बहुत लंबा रास्ता तय करेंगे यदि आपने हर बार पूरी तरह से योग्य नाम का उपयोग किया था। यह विशेष रूप से (अब, शुक्रिया, ज्यादातर अप्रचलित) बूस्ट लैम्ब्डा लाइब्रेरी के लिए सच था, जहां आपने _1 जैसे प्लेसहोल्डर्स का उपयोग किया था, जो boost::lambda::placeholders::_1 जैसे कुछ समाप्त हो गए थे (लेकिन मैं स्मृति से जा रहा हूं, इसलिए शायद कम से कम आंशिक रूप से गलत है) यदि आपने पूरी तरह से योग्य नाम का उपयोग करने पर जोर दिया है। यह पहली जगह में लैम्ब्डा लाइब्रेरी का उपयोग करने के उद्देश्य के एक बड़े हिस्से को हराया होगा।

+0

यहां कुछ मूल्यवान जानकारी शामिल है जो मुझे विश्वास है। चीजों पर विचार किया जाना चाहिए क्योंकि यह वास्तव में ** ** ** इन मामलों में पसंद का विकल्प है। इसे लाने के लिए धन्यवाद। – qrikko

+2

हालांकि, मैं कहूंगा कि इस मामले में आप 'std :: swap का उपयोग करके' उपयोग करना पसंद करेंगे; –

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