पूर्वनिर्धारित दोहरे बृहदान्त्र "::" का अर्थ क्या है?


410

मुझे एक कक्षा में एक कोड की यह पंक्ति मिली जिसे मुझे संशोधित करना है:

::Configuration * tmpCo = m_configurationDB;//pointer to current db

और मुझे नहीं पता है कि वास्तव में डबल कॉलन का क्या मतलब है जो कक्षा के नाम से जुड़ा हुआ है। इसके बिना मैं पढ़ूंगा: tmpCoकक्षा के किसी ऑब्जेक्ट को पॉइंटर के रूप में घोषित करना Configuration... लेकिन पूर्वनिर्मित डबल कोलोन मुझे भ्रमित करता है।

मैंने भी पाया:

typedef ::config::set ConfigSet;

7
वास्तव में यह महसूस न करें कि यह एक उत्तर है, इसलिए मैं टिप्पणी करूंगा: en.wikipedia.org/wiki/Scope_resolution_operator । इस संदर्भ में, नग्न का ::अर्थ वैश्विक / अनाम नामस्थान से चर का संदर्भ है।
wkl

जवाबों:


490

यह सुनिश्चित करता है कि वैश्विक नाम स्थान से रिज़ॉल्यूशन आपके द्वारा वर्तमान में नामस्थान पर शुरू करने के बजाय होता है। उदाहरण के लिए, यदि आपके पास दो अलग-अलग वर्ग हैं Configurationजैसे कि:

class Configuration; // class 1, in global namespace
namespace MyApp
{
    class Configuration; // class 2, different from class 1
    function blah()
    {
        // resolves to MyApp::Configuration, class 2
        Configuration::doStuff(...) 
        // resolves to top-level Configuration, class 1
        ::Configuration::doStuff(...)
    }
}

मूल रूप से, यह आपको वैश्विक नामस्थान तक ले जाने की अनुमति देता है, क्योंकि आपका नाम इस मामले में किसी अन्य नाम स्थान के अंदर एक नई परिभाषा के अनुसार बंद हो सकता है MyApp


डबल कॉलन के 2 सेट लगाने का क्या कारण है? इसमें:::Configuration::doStuff(...)
अज़ुरसपोट

@NoniA। क्या आप पूछ रहे हैं कि डबल कॉलन का दूसरा सेट क्या करता है?
फिको

1
@WyattAnderson, कोई 1 सेट नहीं है। मुझे लगता है कि मैं समझता हूं कि ::बीच में दो शब्द नामस्थान या वर्ग और उसके सदस्य को संदर्भित करते हैं। लेकिन 1 के बारे में क्या?
Azurespot

6
@Azurespot कि ओपी क्या पूछता है, यही सवाल इस पोस्ट का जवाब है। यह वैश्विक नाम स्थान से पहचानकर्ता का उपयोग करना सुनिश्चित करता है। फिर से उदाहरण देखें
भूखा भेड़िया

193

::ऑपरेटर गुंजाइश संकल्प ऑपरेटर को फोन किया और सिर्फ इतना है कि, यह गुंजाइश निराकरण करता है। तो, इसके साथ एक प्रकार-नाम उपसर्ग करके, यह आपके कंपाइलर को टाइप के लिए वैश्विक नामस्थान में देखने के लिए कहता है।

उदाहरण:

int count = 0;

int main(void) {
  int count = 0;
  ::count = 1;  // set global count to 1
  count = 2;    // set local count to 2
  return 0;
}

122

पहले से ही उचित जवाब के बहुत सारे। मैं एक सादृश्य के साथ चिपकेगा जो कुछ पाठकों की मदद कर सकता है। जब आप जिस प्रोग्राम को चलाना चाहते हैं, उसके लिए अपना रास्ता खोजते ::हुए फाइलसिस्टम डायरेक्टरी सेपरेटर ' /' की तरह काम करता है । विचार करें:

/path/to/executable

यह बहुत स्पष्ट है - फाइलसिस्टम के पेड़ में उस सटीक स्थान पर केवल एक निष्पादन योग्य, इस विनिर्देश से मेल खा सकता है, प्रभाव के बावजूद। इसी तरह ...

::std::cout

... सी ++ नामस्थान "पेड़" में समान रूप से स्पष्ट है।

इस तरह के निरपेक्ष रास्तों के विपरीत, आप अपने मौजूदा निर्देशिका या अपने वातावरण चर में किसी भी तत्व के तहत सापेक्ष रास्तों को हल करने के लिए अच्छे UNIX गोले (जैसे zsh ) को कॉन्फ़िगर कर सकते हैं , इसलिए यदि , और आप "में" थे , तो ...PATHPATH=/usr/bin:/usr/local/bin/tmp

X11/xterm

... ख़ुशी ख़ुशी मिलेगी /tmp/X11/xtermअगर मिल जाए /usr/bin/X11/xterm, वरना /usr/local/bin/X11/xterm। इसी तरह, कहते हैं कि आप एक नामस्थान में थे X, और एक " using namespace Yप्रभाव" था, तब ...

std::cout

... में से किसी में पाया जा सकता है ::X::std::cout, ::std::cout, ::Y::std::cout, और होने के कारण अन्य स्थानों तर्क पर निर्भर देखने (ADL, उर्फ कोएनिग देखने)। तो, केवल ::std::coutवास्तव में स्पष्ट है कि आप किस वस्तु का अर्थ रखते हैं, लेकिन सौभाग्य से उनके दाहिने दिमाग में कोई भी कभी भी अपनी खुद की कक्षा / संरचना या नाम स्थान नहीं बनाएगा std, और न ही " cout" नामक कुछ भी , इसलिए केवल अभ्यास का उपयोग std::coutकरना ठीक है।

उल्लेखनीय अंतर :

1) गोले ऑर्डरिंग का उपयोग करके पहले मैच का उपयोग करते हैं PATH, जबकि सी ++ एक अस्पष्ट त्रुटि देता है जब आप अस्पष्ट हो।

2) C ++ में, किसी भी प्रमुख गुंजाइश बिना नाम वर्तमान नाम स्थान में, मिलान किया जा सकता है, जबकि अधिकांश यूनिक्स के गोले केवल कि यदि आप रखूँ .में PATH

3) C ++ हमेशा ग्लोबल नेमस्पेस खोजता है (जैसे /आपके होने का अनुमान हैPATH )।

नाम स्थान और प्रतीकों के गवाह पर सामान्य चर्चा

निरपेक्ष ::abc::def::..."रास्तों" का उपयोग करना कभी-कभी आपके द्वारा उपयोग किए जा रहे किसी भी अन्य नामस्थान से आपको अलग करने के लिए उपयोगी हो सकता है, लेकिन वास्तव में आपके पुस्तकालय के ग्राहक कोड का उपयोग करने वाली सामग्री या अन्य पुस्तकालयों पर भी नियंत्रण नहीं होता है। दूसरी ओर, यह आपको प्रतीक के मौजूदा "निरपेक्ष" स्थान पर और अधिक मजबूती से जोड़े देता है, और आपको नामस्थानों में अंतर्निहित मिलान के फायदे याद आते हैं: कम युग्मन, नामस्थानों के बीच कोड की आसान गतिशीलता, और अधिक संक्षिप्त, पठनीय स्रोत कोड ।

कई चीजों के साथ, यह एक संतुलन कार्य है। के तहत पहचानकर्ता के सी ++ स्टैंडर्ड कहते हैं बहुत सारे std::है कि कम "अद्वितीय" से कर रहे हैं cout, कि प्रोग्रामर पूरी तरह से अलग कुछ उनके कोड में के लिए उपयोग कर सकते हैं (उदाहरण के लिए merge, includes, fill, generate, exchange, queue, toupper, max)। दो असंबंधित गैर-मानक पुस्तकालयों में समान पहचानकर्ताओं का उपयोग करने की अधिक संभावना है क्योंकि लेखक आमतौर पर एक-दूसरे के कम-या-जागरूक होते हैं। और पुस्तकालय - C ++ मानक पुस्तकालय सहित - समय के साथ अपने प्रतीकों को बदलते हैं। यह सब संभावित रूप से पुराने कोड को पुन: स्थापित करते समय अस्पष्टता पैदा करता है, खासकर जब एस का भारी उपयोग किया गया हो using namespace: इस अंतरिक्ष में आप जो सबसे बुरा काम कर सकते हैं वह है अनुमतिusing namespaceहेडर के स्कोप से बचने के लिए हेडर में, जैसे कि एक बड़ी मात्रा में प्रत्यक्ष और अप्रत्यक्ष ग्राहक कोड अपने स्वयं के निर्णय लेने में असमर्थ हैं कि किस नाम स्थान का उपयोग करें और अस्पष्टता कैसे प्रबंधित करें।

इसलिए, ::C ++ प्रोग्रामर के टूलबॉक्स में एक अग्रणी एक उपकरण है जो एक ज्ञात क्लैश को सक्रिय रूप से विभाजित करता है, और / या भविष्य की अस्पष्टता की संभावना को समाप्त करता है ...।


8
अच्छी उपमा के लिए +1। उपदेशों का उपयोग लगभग पर्याप्त IMO शिक्षण उपकरण के रूप में नहीं किया जाता है।
ट्रेवर बोयड स्मिथ

38

::गुंजाइश रिज़ॉल्यूशन ऑपरेटर है। इसका उपयोग किसी चीज़ के दायरे को निर्दिष्ट करने के लिए किया जाता है।

उदाहरण के लिए, ::अकेले अन्य सभी नामस्थानों के बाहर वैश्विक गुंजाइश है।

some::thing निम्नलिखित तरीकों में से किसी में व्याख्या की जा सकती है:

  • someएक नाम स्थान है (वैश्विक दायरे में, या वर्तमान एक से अधिक बाहरी गुंजाइश है) और thingएक प्रकार , एक फ़ंक्शन , ऑब्जेक्ट या नेस्टेड नामस्थान है ;
  • someएक है वर्ग वर्तमान क्षेत्र में उपलब्ध है और thingएक है सदस्य वस्तु , समारोह या प्रकार के someवर्ग;
  • एक वर्ग सदस्य फ़ंक्शन में , वर्तमान प्रकार (या वर्तमान प्रकार स्वयं) का someएक आधार प्रकार हो सकता है और thingफिर इस वर्ग का एक सदस्य, एक प्रकार , फ़ंक्शन या ऑब्जेक्ट हो सकता है

आप नेस्टेड स्कोप भी रख सकते हैं, जैसे कि some::thing::bad। यहाँ प्रत्येक नाम एक प्रकार, एक वस्तु या एक नामस्थान हो सकता है। इसके अलावा, अंतिम एक, badएक फ़ंक्शन भी हो सकता है। अन्य नहीं कर सकते, क्योंकि फ़ंक्शन अपने आंतरिक दायरे में कुछ भी उजागर नहीं कर सकते हैं।

इसलिए, आपके उदाहरण पर वापस, ::thingवैश्विक क्षेत्र में केवल कुछ हो सकता है: एक प्रकार, एक फ़ंक्शन, एक ऑब्जेक्ट या एक नाम स्थान।

जिस तरह से आप इसका उपयोग करते हैं, वह बताता है (सूचक घोषणा में प्रयुक्त) कि यह वैश्विक दायरे में एक प्रकार है।

मुझे उम्मीद है कि यह उत्तर पूरा हो गया है और गुंजाइश समाधान को समझने में आपकी मदद करने के लिए पर्याप्त सही है।


2
@obounaim इस कोड पर विचार करें liveworkspace.org/code/3Wabw0$5 class some { protected: int thing; }; class some_ext : public some { float thing; void action(){ some::thing = 42; thing = 666; } }; यहां someएक बेस क्लास है some_extऔर जब आप some::thingकुछ_एक्सएक्स के सदस्य कार्यों में लिखते हैं, तो इसका मतलब thingआधार प्रकार में ऑब्जेक्ट है some। बिना some::, thingअकेले का मतलब thingनिकटतम दायरे में है, अर्थात some_ext::thing। क्या यह अधिक स्पष्ट है?
क्लेम

17

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

यदि पहले कोई बाएं हाथ नहीं है ::, तो यह इस तथ्य को रेखांकित करता है कि आप वैश्विक नामस्थान का उपयोग कर रहे हैं।

उदाहरण के लिए:

::doMyGlobalFunction();


10

इसके बुलाया गुंजाइश रिज़ॉल्यूशन ऑपरेटर, एक छिपे हुए वैश्विक नाम को गुंजाइश रिज़ॉल्यूशन ऑपरेटर का उपयोग करके संदर्भित किया जा सकता है ::
उदाहरण के लिए;

int x;
void f2()
{
   int x = 1; // hide global x
   ::x = 2; // assign to global x
   x = 2; // assign to local x
   // ...
}

10

(यह उत्तर अधिकतर गुग्लरों के लिए है, क्योंकि ओपी ने अपनी समस्या पहले ही हल कर ली है।) ::पूर्वनिर्धारित - स्कोप रेस्ल्यूजन ऑपरेटर - का अर्थ अन्य उत्तरों में वर्णित किया गया है, लेकिन मैं जोड़ना चाहूंगा कि लोग इसका उपयोग क्यों कर रहे हैं।

अर्थ "वैश्विक नामस्थान से नाम लेना है, कुछ और नहीं"। लेकिन इसके लिए स्पष्ट रूप से वर्तनी की आवश्यकता क्यों होगी?

केस का उपयोग करें - नेमस्पेस क्लैश

जब आपके पास वैश्विक नामस्थान और स्थानीय / नेस्टेड नामस्थान में एक ही नाम है, तो स्थानीय का उपयोग किया जाएगा। इसलिए यदि आप वैश्विक एक चाहते हैं, तो इसे पहले से ही बता दें ::। इस मामले को @Wyatt एंडरसन के जवाब में वर्णित किया गया था, प्लिस उसका उदाहरण देखते हैं।

मामले का उपयोग करें - गैर-सदस्य फ़ंक्शन पर जोर दें

जब आप एक सदस्य फ़ंक्शन (एक विधि) लिख रहे हैं, तो अन्य सदस्य फ़ंक्शन को कॉल करता है और गैर-सदस्य (फ्री) फ़ंक्शन को कॉल एक जैसे लगते हैं:

class A {
   void DoSomething() {
      m_counter=0;
      ...
      Twist(data); 
      ...
      Bend(data);
      ...
      if(m_counter>0) exit(0);
   }
   int m_couner;
   ...
}

लेकिन ऐसा हो सकता है कि Twistयह क्लास का एक बहन सदस्य कार्य है A, और Bendएक नि: शुल्क फ़ंक्शन है। यही है, Twistका उपयोग कर सकते हैं और संशोधित m_counerऔरBend नहीं कर सकता। इसलिए यदि आप यह सुनिश्चित करना चाहते हैं कि m_counter0 बचता है, तो आपको जांचना होगा Twist, लेकिन आपको जांचने की आवश्यकता नहीं है Bend

तो इस स्टैंड को और अधिक स्पष्ट रूप से बनाने के लिए, या तो this->Twistपाठक को दिखाने के लिए लिख सकता है Twistजो एक सदस्य फ़ंक्शन है या ::Bendयह दिखाने के लिए लिख सकता है कि Bendयह मुफ़्त है। अथवा दोनों। जब आप रिफ्लेक्टरिंग कर रहे हों या योजना बना रहे हों तो यह बहुत उपयोगी है।


5

:: नाम स्थान को परिभाषित करने वाला एक ऑपरेटर है।

उदाहरण के लिए, यदि आप using namespace std;अपने कोड में उल्लेख किए बिना कूट का उपयोग करना चाहते हैं, तो आप इसे लिखें:

std::cout << "test";

जब किसी नामस्थान का उल्लेख नहीं किया जाता है, तो यह कहा जाता है कि वर्ग वैश्विक नामस्थान का है।


1

"::" गुंजाइश रिज़ॉल्यूशन ऑपरेटर का प्रतिनिधित्व करता है। कार्य / विधियाँ जिनका एक ही नाम है, उन्हें दो अलग-अलग वर्गों में परिभाषित किया जा सकता है। एक विशेष वर्ग गुंजाइश संकल्प ऑपरेटर के तरीकों का उपयोग करने के लिए प्रयोग किया जाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.