2008-10-21 14 views
80

मैं स्थानीय नामस्थान में std :: string और std :: वेक्टर जोड़ने के लिए C++ में 'उपयोग' घोषणा का उपयोग कर रहा हूं (अनावश्यक 'std ::' टाइपिंग को सहेजने के लिए)।सी ++ में "उपयोग" घोषणा का दायरा क्या है?

using std::string; 
using std::vector; 

class Foo { /*...*/ }; 

इस घोषणा पर दायरा क्या है? यदि मैं इसे हेडर में करता हूं, तो क्या यह प्रत्येक सीपीपी फ़ाइल में इन 'उपयोग' घोषणाओं को इंजेक्ट करेगा जिसमें हेडर शामिल है?

+17

बस अगर यह अन्य उत्तरों से स्पष्ट नहीं है: - ** फ़ाइल/शीर्षलेख में फ़ाइल स्कोप पर 'उपयोग' का उपयोग न करें (या 'निर्देश का उपयोग करें)! ** वह होगा हेडर के उपयोगकर्ताओं के लिए सिरदर्द का कारण बनता है। –

+0

असल में, शीर्षलेख ** में एक 'शीर्षक' घोषणा (एक fortiori * निर्देश *) डालें ** ** * यहां तक ​​कि नामस्थान के भीतर भी! * देखें [नामस्थान के भीतर घोषणा का उपयोग करने का दायरा] (http://stackoverflow.com/q/6175705/2025416) समस्याओं के कारण यह कारण है। –

उत्तर

53

जब आप # सी ++ में हेडर फ़ाइल शामिल करते हैं, तो यह उस शीर्ष फ़ाइल में हेडर फ़ाइल की संपूर्ण सामग्री को उस स्थान पर रखता है जिसे आपने स्रोत फ़ाइल में शामिल किया था। इसलिए using घोषणा वाली फ़ाइल समेत प्रत्येक फ़ाइल के शीर्ष पर using घोषणा रखने का सटीक प्रभाव है जिसमें हेडर फ़ाइल शामिल है।

+43

... जो आम तौर पर एक बुरी चीज है। – Catskul

+13

लेकिन यदि आप 'नेमस्पेस' के अंदर 'उपयोग' घोषणा डालते हैं तो यह उस नामस्थान के दायरे तक ही सीमित है, इसलिए आमतौर पर ठीक है (आपकी विशेष आवश्यकताओं और शैली पर सामान्य चेतावनी के साथ)। – Zero

+1

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

5

मामले में उद्धृत मामले में, फ़ाइल ("अनुवाद इकाई"), जिसका अर्थ है हाँ, प्रत्येक फ़ाइल जिसमें यह शामिल है।

आप कक्षा के अंदर उपयोग कथन भी डाल सकते हैं, इस मामले में, यह केवल उस वर्ग के लिए प्रभावी है।

आम तौर पर, यदि आपको हेडर में नेमस्पेस निर्दिष्ट करने की आवश्यकता है, तो हमेशा आवश्यक प्रत्येक पहचानकर्ता को पूरी तरह अर्हता प्राप्त करना सर्वोत्तम होता है।

+0

ध्यान दें कि किसी वर्ग में 'उपयोग' घोषणा एक वर्ग के बाहर जैसी तरह व्यवहार नहीं करती है - उदाहरण के लिए आप इसका उपयोग नहीं कर सकते हैं, कक्षा के दायरे में 'std :: cout' के बजाय' cout' लाएं। – Zero

2

यह सही है। दायरा वह मॉड्यूल है जो using घोषणा का उपयोग करता है। यदि कोई हेडर फाइलें जिसमें मॉड्यूल में using घोषणाएं हैं, तो उन घोषणाओं का दायरा उस मॉड्यूल के साथ-साथ अन्य मॉड्यूल भी होगा जिसमें एक ही शीर्षलेख शामिल होंगे।

86

हेडर फाइलों के बारे में कुछ खास नहीं है जो using घोषणा को बनाए रखेगा। संकलन शुरू होने से पहले यह एक साधारण पाठ प्रतिस्थापन है। यदि यह वैश्विक गुंजाइश है

void myFunction() 
{ 
    using namespace std; // only applies to the function's scope 
    vector<int> myVector; 
} 
+8

मैंने कभी सोचा नहीं कि मैं इसे एक समारोह के अंदर उपयोग कर सकता हूं! – Agostino

+1

मुझे नामों का एक गुच्छा मिला है जो सभी एक "समूह" -टाइप फ़ाइल द्वारा उपयोग किए जा रहे हैं, और जीएमॉक यूनिट-परीक्षण अतिरिक्त थकाऊ था क्योंकि प्रत्येक परीक्षण ने विशिष्ट नामस्थान से चीजों का उपयोग किया था, और मैंने सोचा कि मुझे प्रत्येक और प्रत्येक चर । फ़ंक्शन के अंदर 'उपयोग' का उपयोग करना (या यहां तक ​​कि एक gtest 'टेस्ट' मैक्रो!) मेरे जीवन को इतना बेहतर बनाता है! – dwanderson

4

गुंजाइश जो कुछ गुंजाइश घोषणा का उपयोग करने में है

, तो यह वैश्विक क्षेत्र में हो जाएगा:

आप एक गुंजाइश के लिए एक using घोषणा सीमित कर सकते हैं।। यदि यह हेडर फ़ाइल के वैश्विक दायरे में है, तो यह शीर्ष स्रोत फ़ाइल के वैश्विक दायरे में होगा जिसमें हेडर शामिल है।

तो, सामान्य सलाह हैडर फाइलों के वैश्विक दायरे में घोषणाओं का उपयोग करने से बचें

+2

यह पर्याप्त मजबूत नहीं है। –

+1

से बचें से बचें BUt से बचने से अधिक मजबूत है। "अन्य कारों को मारने से बचें" – bobobobo

44

कथन का उपयोग का दायरा जहां यह कोड में स्थित है पर निर्भर करता है:

  • एक फ़ाइल के शीर्ष पर नहीं डाला जा सकता है, यह है कि फाइल भर गुंजाइश है।
  • यदि यह एक हेडर फ़ाइल है, तो उस शीर्षलेख में सभी फ़ाइलों में इसका दायरा होगा। सामान्य तौर पर, यह "नहीं एक अच्छा विचार" यह अप्रत्याशित दुष्प्रभाव
  • अन्यथा का उपयोग कर बयान ब्लॉक है कि यह बात यह ब्लॉक के अंत में होता है से होता है के भीतर गुंजाइश है हो सकता है के रूप में। यदि इसे किसी विधि के भीतर रखा गया है, तो उस विधि के भीतर इसका दायरा होगा। यदि इसे कक्षा परिभाषा के भीतर रखा गया है तो उस वर्ग के भीतर इसका दायरा होगा।
+4

मैंने सोचा कि क्लास स्कोप के भीतर 'उपयोग' कथन जोड़ना संभव नहीं था ...? मेरे पास ओपी के समान प्रश्न था क्योंकि मैं उस स्थान पर 'std ::' टाइपिंग से बचना चाहता था। मुझे कक्षाएं मिलीं जो स्मार्ट पॉइंटर्स के साथ बहुत से वैक्टर का उपयोग करती हैं और पांच वर्ण 'std ::' उपसर्ग में बहुत सी रेखा लंबाई शामिल होती है - जो मुझे लगता है कि बदतर पढ़ता है। तो मैं सोच रहा था कि वर्ग युक्त नामस्थान के भीतर 'उपयोग' निर्देश सही था या नहीं? (यहां तक ​​कि यदि शीर्षलेख में भी।) – thomthom

+0

क्या यह 'नेमस्पेस {...}' के दायरे में रखा गया है? – einpoklum

+0

तो आप पूरी तरह से लिख सकते हैं: {नेमस्पेस ब्लैब्ला का उपयोग करना; कक्षा ब्लाह {}; } और इसका उपयोग केवल कक्षा में ही लागू होगा? – Dinaiz

1

कुछ टिप्पणियां हैं जो "नहीं" कहने पर अयोग्य हैं।यह बहुत कठोर है, लेकिन आपको समझना होगा कि यह ठीक है।

लेखन using std::string कभी ठीक नहीं है। अपने हेडर में using ImplementationDetail::Foo लिखते समय, जब वह हेडर कार्यान्वयन की घोषणा करता है डिक्शनरी :: फू ठीक हो सकता है, अगर आपके नामस्थान में उपयोग की घोषणा हो रही है तो मोर्सो। जैसे

namespace MyNS { 
    namespace ImplementationDetail { 
     int Foo; 
    } 
    using ImplementationDetail::Foo; 
} 
+1

हेडर का उपयोगकर्ता 'MyNS :: Foo' –

+0

लिख सकता है एक बेहतर उदाहरण है' boost :: posix_time :: ptime' का उपयोग करना। निश्चित रूप से उपयोगकर्ता 'MyNS :: ptime' लिख सकता है लेकिन यह दुनिया का अंत नहीं है, और' MyFunction (ptime a, ptime b) जैसे कार्यों को प्राप्त करने में सक्षम होने की सुविधा से ऑफसेट हो सकता है। – Zero

+4

* क्यों * std :: string' का उपयोग कर रहा है ठीक नहीं है? बहुत से 'std ::' उपसर्गों को सहेजने के लिए भी अपने नामस्थान में? – thomthom

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