2013-06-25 11 views
11

जब मैं कोड निम्नलिखित लिखने यह संकलित हो जाता है और ठीक से मार डाला:वैश्विक दायरे और स्थानीय दायरे में निर्देश का उपयोग क्यों अलग-अलग व्यवहार करते हैं?

#include <iostream> 
using namespace std; 

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 

namespace second 
{ 
    double x = 3.1416; 
    double y = 2.7183; 
} 

int main() { 
    using namespace first; //using derective 
    using second::y; 
    cout << x << endl; 
    cout << y << endl; 
    return 0; 
} 

लेकिन अगर मैं इस प्रकार मुख्य कार्य के बाहर निर्देशों का उपयोग कर लिखते हैं,

using namespace first; //using derective 
using second::y; 
int main() { 
    cout << x << endl; 
    cout << y << endl; 
    return 0; 
} 

यह इस संकलन त्रुटि देता है:

g++  namespace03.cpp -o namespace03 
namespace03.cpp: In function ‘int main()’: 
namespace03.cpp:20:11: error: reference to ‘y’ is ambiguous 
namespace03.cpp:13:10: error: candidates are: double second::y 
namespace03.cpp:7:7: error:     int first::y 
make: *** [namespace03] Error 1 

क्या कोई यह बता सकता है कि main के अंदर औरके अंदर उपयोग किए जाने पर निर्देश का उपयोग क्यों अलग-अलग व्यवहार करता है?

उत्तर

10

उपयोग-घोषणा केवल एक घोषणा है। मुख्य के अंदर using second::y; एक वैरिएबल y को उस दायरे में घोषित करने जैसा है जो वैश्विक नामस्थान स्कोप में किसी अन्य y एस को छुपाता है। जब आप वैश्विक दायरे में using second::y; का उपयोग करते हैं, तो आपने किसी भी नाम को छुपाया नहीं है, क्योंकि y दोनों एक ही दायरे में हैं।

कल्पना कीजिए अपना पहला उदाहरण की तरह है निम्नलिखित (कृपया एक विवरण के लिए नीचे टिप्पणी देखें):

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 

int main() { 
    using namespace first; // This makes first::y visible hereafter 
    int y = 20; // This hides first::y (similar to using second::y) 
    cout << x << endl; 
    cout << y << endl; // Prints 20 
} 

हालांकि, दूसरे उदाहरण की तरह है:

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 
using namespace first; // This makes first::y visible in global scope 
int y = 20; // This is global ::y 
int main() { 
    cout << x << endl; 
    cout << y << endl; // Error! Do you mean ::y or first::y? 
} 
+0

त्वरित उत्तर के लिए जेसी धन्यवाद ... अगर मैं गलत हूं तो कृपया मुझे सही करें ... लेकिन जब निर्देशों का उपयोग मुख्य कार्य में होता है तब भी वाई की 2 घोषणाएं होने वाली हैं। यदि ऐसा है तो संकलक केवल दूसरे मामले में समस्या क्यों देता है? – Amrit

+1

@ user2235938: 'y' की दो घोषणाएं हैं, लेकिन उपयोग-घोषणा मुख्य के अंदर' second :: y' घोषित करती है, जबकि 'प्रथम :: y' को वैश्विक नामस्थान क्षेत्र में घोषित किया जाता है। चूंकि मुख्य के अंदर 'second :: y' घोषित किया गया है, यह 'पहले :: y' छुपाता है। क्या आप नाम छिपाने से परिचित हैं? –

+0

क्षमा करें जेसी ... लेकिन मैं समझने में सक्षम नहीं हूं। जब दोनों कथन "नामस्थान का उपयोग करते हुए पहले; दूसरे :: y का उपयोग करते हुए;" मुख्य कार्य के अंदर हैं, इसे स्थानीय क्षेत्र में पहले :: y और second :: y दोनों घोषित करना चाहिए और संकलन त्रुटि देना चाहिए। लेकिन यह प्रोग्राम और संकलित नहीं करता है और सफलतापूर्वक चलता है। और जब दोनों कथन मुख्य रूप से बाहर होते हैं तो यह अस्पष्टता के कारण भी संकलित नहीं होता है। कृपया समझाएं ... – Amrit

6

दो प्रमुख मतभेद नहीं है उपयोग-घोषणा और उपयोग-निर्देश के बीच।

पहला अंतर: (स्पष्ट अंतर)।

namespace first{ 

int x=1; 
int y=2; 
} 
using first::x; //using declaration 

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

namespace first{ 
int x=1; 
int y=2; 
} 
using namespace first;// using directive 

यह आपको एक स्पष्ट क्वालीफायर के रूप में बिना नाम स्थान नाम नाम स्थान first के अंदर सभी चर का उपयोग करने की अनुमति देगा।


दूसरा अंतर: (जो आप समझ में नहीं आया कि क्या है)।

मैं आपको समझाऊंगा कि जब आप मुख्य कार्य के अंदर उपयोग-निर्देश और उपयोग-घोषणा दोनों का उपयोग करते हैं तो आपको कोई त्रुटि नहीं मिलती है, लेकिन जब आप वैश्विक नामस्थान में दोनों का उपयोग करने का प्रयास करते हैं तो आपको संकलन-समय त्रुटि मिलती है।

चलें कहते हैं कि हम दो नाम स्थान इस तरह वैश्विक नामस्थान में परिभाषित किया गया है:

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 

namespace second 
{ 
    double x = 3.1416; 
    double y = 2.7183; 
} 


उदाहरण 1:

int main() {  
using namespace first; 
using second::y; 
    cout << x << endl; // this will output first::x; 
    cout << y << endl; // this will output second::y; 
    return 0; 
} 

कारण है कि का उपयोग कर-निर्देश using second::y आपके चर y को ऐसा लगता है कि यह एक स्थानीय चर है जो using-directive है sed, इस मामले में यह मुख्य समारोह के अंदर प्रयोग किया जाता है। जबकि उपयोग घोषणा using namespace first इस नामस्थान first के अंदर परिभाषित चर को वैरिएबल बना देगा जैसे वे वैश्विक चर हैं और यह केवल उस दायरे के अंदर मान्य है जहां उपयोग-निर्देश का उपयोग किया गया था, इस मामले में यह मुख्य कार्य के अंदर है।

इसलिए यदि आप लागू what've ऊपर कहा, आपको पता चलेगा कि आप कुछ इस तरह किया है, तो:

उदाहरण 2:

using namespace first; 
using second::y; 

int main() {  
    cout << x << endl; 
    cout << y << endl; // two definitions of y. first::y and second::y 
    return 0; 
} 

आपको एक त्रुटि मिल जाएगा, दोनों first::y के बाद से और second::y व्यवहार करेंगे जैसे कि उन्हें वैश्विक नामस्थान में परिभाषित किया गया था, इसलिए आप एक परिभाषा नियम को तोड़ने के साथ समाप्त हो जाएंगे।

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