मैंने इन दो वाक्यांशों का उपयोग देखा: वैश्विक दायरा और वैश्विक नामस्थान। उनके बीच क्या अंतर है?ग्लोबल स्कोप बनाम वैश्विक नामस्थान
उत्तर
सी ++ में, प्रत्येक नाम का दायरा बाहर है जिसके बाहर यह मौजूद नहीं है। एक गुंजाइश कई मायनों से परिभाषित किया जा सकता है: यह नाम स्थान, कार्यों, कक्षाएं और बस {} से परिभाषित किया जा सकता है।
तो नामस्थान, वैश्विक या अन्यथा, एक दायरा परिभाषित करता है। वैश्विक नामस्थान ::
का उपयोग करने के लिए संदर्भित करता है, और इस नामस्थान में परिभाषित प्रतीकों को वैश्विक क्षेत्र कहा जाता है। एक प्रतीक, डिफ़ॉल्ट रूप से, एक वैश्विक नाम स्थान में, जब तक यह परिभाषित किया गया है मौजूद है अंदर एक ब्लॉक कीवर्ड namespace
के साथ शुरू होता है, या यह एक वर्ग के एक सदस्य, या एक समारोह के एक स्थानीय चर रहा है:
int a; //this a is defined in global namespace
//which means, its scope is global. It exists everywhere.
namespace N
{
int a; //it is defined in a non-global namespace called `N`
//outside N it doesn't exist.
}
void f()
{
int a; //its scope is the function itself.
//outside the function, a doesn't exist.
{
int a; //the curly braces defines this a's scope!
}
}
class A
{
int a; //its scope is the class itself.
//outside A, it doesn't exist.
};
यह भी ध्यान रखें कि नाम नामस्थान, फ़ंक्शन या कक्षा द्वारा परिभाषित आंतरिक दायरे से छुपाया जा सकता है। तो नेमस्पेस N
के अंदर a
नाम वैश्विक नाम में a
नाम छुपाता है। इसी तरह, फ़ंक्शन और कक्षा में नाम वैश्विक नामस्थान में नाम छुपाता है। आप इस तरह के स्थिति का सामना है, तो आप नाम ग्लोबल नेम स्पेस में परिभाषित का उल्लेख करने के ::a
उपयोग कर सकते हैं:
int a = 10;
namespace N
{
int a = 100;
void f()
{
int a = 1000;
std::cout << a << std::endl; //prints 1000
std::cout << N::a << std::endl; //prints 100
std::cout << ::a << std::endl; //prints 10
}
}
जब आप उदाहरण के लिए एक वैश्विक चर int i
घोषित, हम i is in the global namespace
और has the global namespace scope
का कहना है। बस इतना ही। सी ++ 03 से
अंश:
3.3.5 Namespace scope
The outermost declarative region of a translation unit is also a namespace, called
the global namespace. A name declared in the global namespace has global namespace
scope (also called global scope).
"स्कोप" "नाम स्थान" की तुलना में एक अधिक सामान्य शब्द है। प्रत्येक नेमस्पेस, कक्षा और कोड ब्लॉक एक दायरे को परिभाषित करता है जिसमें इसके अंदर घोषित नामों का उपयोग किया जा सकता है; एक नामस्थान कक्षाओं और कार्यों के बाहर घोषित नामों के लिए एक कंटेनर है।
"वैश्विक क्षेत्र" और "वैश्विक नामस्थान" का उपयोग कम से कम एक-दूसरे से किया जा सकता है; नामस्थान में घोषित नाम का दायरा उस पूरे नामस्थान को कवर करता है। यदि आप विशेष रूप से नामस्थान का जिक्र कर रहे हैं, और "स्कोप" का उपयोग करते हैं तो "नेमस्पेस" का उपयोग करें यदि आप इसके अंदर नामों की दृश्यता का जिक्र कर रहे हैं।
स्कोप किसी ऑब्जेक्ट के जीवनकाल को इंगित करता है, तो आपके पास एक वैश्विक चर हो सकता है जो आपके प्रोग्राम निष्पादित होने तक अस्तित्व में रहेगा, या आपके पास एक ब्लॉक स्कोप वाला चर हो सकता है जो कोड के उस ब्लॉक को निष्पादित करता है। इस उदाहरण पर विचार:
#include <iostream>
int a = 100;
main() {
int a = 200;
std::cout << "local a is: " << a << std::endl;
std::cout << "global a is: " << ::a << std::endl;
return 0;
}
जब बयान local a is: 200
प्रिंट होगा मार डाला, जो स्पष्ट रूप से उम्मीद है, क्योंकि हम main
जो दायरे में छोड़ देता है की यह ब्लॉक संलग्न है में a
को पुनर्परिभाषित कर रहे हैं। हम वैश्विक ::a
भी प्रिंट करते हैं जो फिर से अपेक्षित मूल्य 100 प्रिंट करता है, क्योंकि हमने वैश्विक नामस्थान ::
के लिए कहा है।
एक नामस्थान अर्थशास्त्र ज्यादातर तार्किक हैं, यह एक दूसरे से सिंबल को अलग करने का एक तरीका है, नाम संघर्ष से बचने की उम्मीद में, यह किसी वस्तु के जीवनकाल को प्रभावित नहीं करता है।
दूसरी ओर दायरा, किसी ऑब्जेक्ट के जीवनकाल को दर्शाता है, वैश्विक a
स्थानीय a
से पहले अस्तित्व में उभरा क्योंकि यह मुख्य रूप से निष्पादित होने से पहले बहुत पहले बनाया जाता है। हालांकि, स्कॉप्स प्रतीक पर एक नामस्थान है, लेकिन उसी तरह से नहीं है कि namespace
करता है। स्कोप के विभिन्न प्रकार, global
, class
, function
, block
, file
आदि कर रहे हैं ...
भ्रामक बात यह है कि कभी कभी गुंजाइश एक विशेष प्रतीक की दृश्यता है, जो कुछ सी, जहां से लिया गया है निरूपित करने के लिए ओवरलोड हो गया है नामस्थानों की धारणा मौजूद नहीं थी और दोनों का जीवनकाल और दृश्यता को दर्शाने के लिए गुंजाइश का उपयोग किया गया था। सी ++ में, हालांकि नियम थोड़ा बदल गए, लेकिन शब्द शब्द अभी भी उसी तरह उपयोग किया जाता है क्योंकि दोनों भाषाएं अवधारणाओं का एक बड़ा सौदा साझा करती हैं।
अच्छा है कि आपने इस विचार को हाइलाइट किया कि एक गुंजाइश किसी ऑब्जेक्ट के जीवनकाल में निहित है। –
@Dmitriy Ryajov
विषय एक छोटा सा पुराना है, लेकिन मैं इस बारे में मेरी मदद की पेशकश करना चाहते हैं। मुझे लगता है कि आपको वास्तव में चीजों की तुलना में अधिक जटिल नहीं बनाना चाहिए। एक पहचानकर्ता के Scope
एक कंप्यूटर प्रोग्राम का हिस्सा है जहां पहचानकर्ता, एक नाम जो प्रोग्राम में कुछ इकाई को संदर्भित करता है, का उपयोग निर्दिष्ट इकाई को खोजने के लिए किया जा सकता है। तो शब्द का दायरा केवल पहचानकर्ताओं पर लागू होता है और हमें इसे वस्तु के जीवनकाल के साथ मिश्रण नहीं करना चाहिए। वे कुछ हद तक जुड़े हुए हैं लेकिन उन्हें मिश्रित नहीं किया जाना चाहिए। ऑब्जेक्ट का जीवनकाल उस वस्तु के लिए स्मृति आवंटित करता है, जहां दर्शाया जाता है। इसलिए, उदाहरण के लिए, यदि स्टैक पर एक स्मृति आवंटित की जाती है, तो जैसे ही फ़ंक्शन समाप्त हो जाता है, इसे मुक्त कर दिया जाएगा। तो यह इस बात पर निर्भर करता है कि हम वस्तु को कहां स्टोर करते हैं और जो इसके जीवनकाल को दर्शाता है। दायरा केवल कहता है: "यहां किसी ऑब्जेक्ट का नाम है और हम तब तक ऑब्जेक्ट के लिए इस नाम का उपयोग कर सकते हैं"। इसलिए, जैसा कि मैंने कहा था, scope
शब्द केवल वस्तुओं के पहचानकर्ताओं के लिए है और जीवनकाल कुछ और है जिसे हम ऑब्जेक्ट को स्टोर करते हैं।
इसके अतिरिक्त, मैं linkage
के बारे में कुछ कहना चाहता हूं जो इससे निकटता से संबंधित है। यह कभी-कभी भ्रमित भी हो सकता है। आइए मान लें कि हमारे पास translation unit
में कुछ पहचानकर्ता हैं जो कुछ ऑब्जेक्ट्स का संदर्भ देते हैं। चाहे other
अनुवाद इकाई में वही पहचानकर्ता संदर्भित हों, वही इकाइयों को संदर्भ द्वारा दर्शाया गया है। इसलिए, उदाहरण के लिए, यदि किसी पहचानकर्ता के पास बाहरी संबंध है, तो हम उस इकाई को संदर्भित कर सकते हैं जो इस पहचानकर्ता को संदर्भित करता है लेकिन अन्य अनुवाद इकाई से इसे कीवर्ड extern
के साथ घोषित करके संदर्भित करता है। अब, मान लीजिए कि हम उस इकाई का उपयोग अन्य अनुवाद इकाइयों में नहीं करना चाहते हैं। फिर, प्रोग्राम खत्म होने तक exist
होगा लेकिन जब हम इसे घोषित नहीं करेंगे, तो हम इसका उल्लेख नहीं कर पाएंगे। यह भी ध्यान रखें कि अब मैंने शब्दों और जीवनकाल को मिश्रित किया है। लेकिन ऐसा इसलिए है क्योंकि केवल global
इकाइयों में बाहरी संबंध है। किसी फ़ंक्शन के अंदर एक पहचानकर्ता प्रोग्राम के अन्य हिस्सों से नहीं बदला जा सकता है।
निष्कर्ष: हमेशा चीजों को सरल रखने की कोशिश करें। मैं आश्चर्यचकित था कि लोग इन शर्तों के बारे में अलग-अलग बात करते हैं। अलग संकलन की पूरी प्रक्रिया भ्रमित है, क्योंकि ऐसे कई शब्द हैं जिनके लगभग समान अर्थ हैं और शायद इस बिंदु पर हर कोई फंस जाएगा।
अगर हम फ़ंक्शन शून्य() {} – rimiro
@rimiro के अंदर 'ए' (नामस्थान एन में परिभाषित) तक पहुंचना चाहते हैं तो हमें क्या करना चाहिए: यदि किसी फ़ंक्शन स्कोप में 'ए' घोषित किया गया है, तो आप इसे * * समारोह के बाहर। – Nawaz