প্রপেন্ডড ডাবল কোলন "::" এর অর্থ কী?


410

আমি একটি ক্লাসে একটি কোডের এই লাইনটি পেয়েছি যা আমাকে সংশোধন করতে হবে:

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

এবং আমি জানি না ডাবল কোলন শ্রেণীর নামের সাথে সংশোধিত হুবহু অর্থ কী। তা ছাড়া আমি পড়তে পারি: tmpCoশ্রেণীর কোনও বস্তুর কাছে পয়েন্টার হিসাবে ঘোষণা Configuration... তবে চাপানো ডাবল কোলন আমাকে বিভ্রান্ত করে।

আমি এটিও পেয়েছি:

typedef ::config::set ConfigSet;

7
সত্যিই এটি একটি উত্তর বলে মনে করবেন না, তাই আমি মন্তব্য করব: en.wikedia.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
@ ওয়াইটএন্ডারসন, 1 ম সেট নেই। আমি মনে করি যে আমি বুঝতে পারি যে ::মধ্যে-দুটি পদ শর্তাবলী নামস্থান বা শ্রেণি এবং এর সদস্যকে বোঝায়। কিন্তু 1 ম সম্পর্কে কি?
Azurespot

6
@ আজুরস্পট এটাই যে ওপি জিজ্ঞাসা করে, এটাই এই পোস্টের উত্তর দেয়। এটি বিশ্বব্যাপী নেমস্পেস থেকে সনাক্তকারী ব্যবহার করা নিশ্চিত করে। উদাহরণটি আবার দেখুন
ক্ষুধার্ত ওল্ফ

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

... সি ++ নেমস্পেস "ট্রি" তে সমানভাবে স্পষ্ট।

এ জাতীয় নিখুঁত পাথের সাথে বিপরীতে, আপনি আপনার বর্তমান ডিরেক্টরিতে বা আপনার পরিবেশে পরিবর্তনশীল কোনও উপাদানের অধীন আপেক্ষিক পাথগুলি সমাধান করতে ভাল ইউনিক্স শেল (উদাঃ 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, ওরফে Koenig লুকআপ)। সুতরাং, ::std::coutঠিক কোনটি অবজেক্ট বলতে চাইছেন সে সম্পর্কে কেবল সত্যই স্পষ্টভাবে বলা যায়, তবে ভাগ্যক্রমে তাদের সঠিক মনের কেউই তাদের " std" নামক একটি নিজস্ব শ্রেণি / কাঠামো বা নেমস্পেস তৈরি করতে পারে না, " cout" নামক কোনও কিছুই তৈরি করে না , সুতরাং কেবল ব্যবহারে অনুশীলন std::coutকরা ভাল।

লক্ষণীয় পার্থক্য :

1) শেলগুলি ক্রমটি ক্রমটি ব্যবহার করে প্রথম ম্যাচটি ব্যবহার করার প্রবণতা PATHদেখায়, যখন আপনি অস্পষ্ট হন তখন সি ++ একটি সংকলক ত্রুটি দেয়।

2) C ++, কোনো নেতৃস্থানীয় সুযোগ ছাড়া নাম বর্তমান নামস্থান এ, মিলেছে করা যাবে যখন সবচেয়ে ইউনিক্স শেল শুধুমাত্র যে আপনি যদি করা না .মধ্যে PATH

3) সি ++ সর্বদা বিশ্বব্যাপী নেমস্পেস অনুসন্ধান করে (যেমন /আপনার স্পষ্টতই থাকে PATH)।

নেমস্পেস এবং প্রতীকগুলির স্পষ্টবাদী সম্পর্কিত সাধারণ আলোচনা

নিখুঁত ::abc::def::..."পাথ" ব্যবহার করা আপনি কখনও কখনও ব্যবহার করছেন এমন অন্য কোনও স্থানের স্থান থেকে আপনাকে বিচ্ছিন্ন করতে দরকারী হতে পারে, তবে এর অংশবিশেষ বা আপনার লাইব্রেরির ক্লায়েন্ট কোডটি ব্যবহার করে এমন অন্যান্য লাইব্রেরির সামগ্রীর উপরও সত্যই নিয়ন্ত্রণ নেই। অন্যদিকে, এটি আপনাকে প্রতীকের বিদ্যমান "পরম" অবস্থানের সাথে আরও দৃ tight়ভাবে যুক্ত করে, এবং আপনি নামের জায়গাগুলিতে অন্তর্নিহিত মিলের সুবিধাগুলি হারাতে পারেন: কম সংযুক্তি, নেমস্পেসগুলির মধ্যে কোডের সহজ গতিশীলতা এবং আরও সংক্ষিপ্ত, পাঠযোগ্য উত্স কোড ।

অনেক কিছুর মতো এটিও ভারসাম্যপূর্ণ কাজ। অধীনে অভিন্ন পরিচয় সি ++ স্ট্যান্ডার্ড রাখে প্রচুর std::কম "অনন্য" তুলনায় cout, যাতে প্রোগ্রামারদের সম্পূর্ণ ভিন্ন কিছু তাদের কোড এ জন্য ব্যবহার করতে পারে (যেমন merge, includes, fill, generate, exchange, queue, toupper, max)। দুটি অপ্রাসঙ্গিক অ-স্ট্যান্ডার্ড লাইব্রেরির লেখকরা একে অপরের সম্পর্কে সাধারণত অ-বা কম সচেতন হওয়ায় একই শনাক্তকারীদের ব্যবহারের আরও বেশি সুযোগ রয়েছে। এবং লাইব্রেরিগুলি - সি ++ স্ট্যান্ডার্ড লাইব্রেরি সহ - সময়ের সাথে সাথে তাদের প্রতীকগুলি পরিবর্তন করে। পুরানো কোডটি সংশোধন করার সময় এই সমস্ত সম্ভাব্য দ্ব্যর্থতা তৈরি করে, বিশেষত যখন এর অত্যধিক ব্যবহার হয় using namespace: আপনি এই জায়গায় সবচেয়ে খারাপ কাজ করতে পারবেনusing namespaceশিরোনামের স্কোপগুলি এড়াতে শিরোলেখগুলিতে, যেমন কোনও নাম স্থান এবং কীভাবে অস্পষ্টতা পরিচালনা করা যায় সে সম্পর্কে একটি নির্বিচারে প্রচুর প্রত্যক্ষ এবং অপ্রত্যক্ষ ক্লায়েন্ট কোড তাদের নিজের সিদ্ধান্ত নিতে অক্ষম।

সুতরাং, একটি শীর্ষস্থানীয় ::হ'ল সি ++ প্রোগ্রামারের টুলবক্সে সক্রিয়ভাবে একটি পরিচিত সংঘর্ষকে নিস্ক্রিয় করতে এবং / অথবা ভবিষ্যতের অস্পষ্টতার সম্ভাবনা দূর করার জন্য একটি সরঞ্জাম ....


8
ভাল উপমা জন্য +1। উপমাগুলি প্রায় একটি শিক্ষণ সরঞ্জাম হিসাবে আইএমও ব্যবহার করা হয় না।
ট্রেভর বয়েড স্মিথ

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

(এই উত্তরটি বেশিরভাগ গুগলারের পক্ষে, কারণ ওপি ইতিমধ্যে তার সমস্যার সমাধান করেছে)) চাপ দেওয়া অর্থ :: অন্য উত্তরগুলিতে প্রপেন্ড করা - স্কোপ রিসুলেশন অপারেটর - বর্ণিত হয়েছে, তবে আমি কেন যুক্ত করতে চাই তা যুক্ত করতে চাই।

এর অর্থ হ'ল "বিশ্বব্যাপী নেমস্পেস থেকে নাম গ্রহণ করুন, অন্য কিছু নয়"। তবে কেন এটি স্পষ্টভাবে বানান করা দরকার?

কেস ব্যবহার করুন - নেমস্পেস সংঘর্ষ

যখন আপনার বিশ্বব্যাপী নেমস্পেসে এবং স্থানীয় / নেস্টেড নেমস্পেসে একই নাম থাকবে, স্থানীয় একটি ব্যবহৃত হবে। সুতরাং আপনি যদি বিশ্বব্যাপী এক চান, এটি দিয়ে প্রিপেন্ড করুন ::। এই মামলাটি @ ওয়াট অ্যান্ডারসনের উত্তরে বর্ণিত হয়েছিল, দয়া করে তার উদাহরণটি দেখুন।

কেস ব্যবহার করুন - অ-সদস্য ফাংশনের উপর জোর দিন

আপনি যখন কোনও সদস্য ফাংশন (একটি পদ্ধতি) লিখছেন, অন্য সদস্য ফাংশনে কল করে এবং সদস্যবিহীন (ফ্রি) ফাংশনগুলিতে একই চেহারা দেখায়:

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

"::" স্কোপ রেজুলেশন অপারেটরকে উপস্থাপন করে। একই নাম রয়েছে এমন কার্য / পদ্ধতিগুলি দুটি পৃথক শ্রেণিতে সংজ্ঞায়িত করা যায়। কোনও নির্দিষ্ট শ্রেণীর স্কোপ রেজোলিউশন অপারেটরের পদ্ধতিগুলি অ্যাক্সেস করতে ব্যবহার করা হয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.