Что означает добавленное двойное двоеточие "::"?



Я нашел эту строку кода в класс, который я должен изменить:



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


и я не знаю, что именно означает двойное двоеточие перед именем класса. Без этого я бы прочитал: объявление tmpCo как указатель на объект класса Configuration... но добавленная двойная двоеточие сбивает меня с толку.



Я нашел:



typedef ::config::set ConfigSet;
799   8  

8 ответов:

это гарантирует, что разрешение происходит из глобального пространства имен, а не начинается с пространства имен, в котором вы находитесь в данный момент. Например, если у вас было два разных класса под названием 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.

The :: оператор называется оператором scope-resolution и делает именно это, он разрешает область. Таким образом, путем префикса имени типа с этим, он говорит вашему компилятору искать в глобальном пространстве имен для типа.

пример:

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;
}

много разумных ответов уже. Я скинусь с аналогией, которая может помочь некоторым читателям. :: работает очень похоже на разделитель каталогов файловой системы'/', при поиске вашего пути для программы, которую вы хотели бы запустить. Рассмотрим:

/path/to/executable

это очень явно-только исполняемый файл в этом точном месте в дереве файловой системы может соответствовать этой спецификации, независимо от пути в действительности. Аналогично...

::std::cout

...столь же явного в пространстве имен C++ "дерево".

в отличие от таких абсолютных путей, вы можете настроить хорошие оболочки UNIX (например, zsh) для разрешения относительные пути под любым элементом в вашем PATH переменная окружения, так что если PATH=/usr/bin:/usr/local/bin, затем...

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, и, возможно, в других местах из-за

:: - оператор разрешения области. Он используется для указания области действия чего-либо.

например, :: только глобальная область, вне всех других пространств имен.

some::thing можно интерпретировать любым из следующих способов:

  • some - это пространство имен (в глобальной области или внешней области, чем текущая) и thing это тип, a функции, an объект или вложенные пространства имен;
  • some - это класс доступных в текущей области и thing это член,функции или тип на some класс;
  • в функции-члене класса,some может быть тип основания текущего типа (или самого текущего типа) и thing тогда один член этого класса, a тип,функции или объект.

вы также можете иметь вложенную область, как в some::thing::bad. Здесь каждое имя может быть типом, объектом или пространством имен. Кроме того, последний, bad, также может быть функцией. Другие не могли,так как функции не могут ничего раскрывать в своей внутренней области.

Итак, вернемся к вашему примеру, ::thing может быть только что-то в глобальной области видимости: тип, функция, объект или пространство имен.

способ его использования предполагает (используется в объявлении указателя), что это тип в глобальной области.

Я надеюсь, что этот ответ является полным и достаточно правильным, чтобы помочь вам понять разрешение области.

:: используется для связывания чего-либо (переменной, функции, класса, typedef и т. д...) в пространство имен или в класс.

если нет левой стороны перед ::, то это подчеркивает тот факт, что вы используете глобальное пространство имен.

например:

::doMyGlobalFunction();

вызывается оператор разрешения области, скрытое глобальное имя может быть указано с помощью оператора разрешения области::
Например:

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

(этот ответ в основном для гуглеров, потому что ОП уже решил свою проблему.) Значение прилагаемого :: - scope resulution operator-был описан в других ответах, но я хотел бы добавить, почему люди используют его.

смысл "брать имя из глобального пространства имен, а не что-нибудь еще". Но почему это должно быть написано явно?

случае использовать - столкновение пространства имен

когда у вас есть то же имя в глобальной пространство имен и в локальном / вложенном пространстве имен будет использоваться локальное пространство имен. Поэтому, если вы хотите глобальный, добавьте его с ::. Этот случай был описан в ответе @ Wyatt Anderson, plese см. Его пример.

Use case-подчеркните функцию, не являющуюся членом

когда вы пишете функцию-член (метод), вызовы других функций-членов и вызовы нечленов (свободных) функций выглядят одинаково:

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_counter остается 0, вы должны проверить Twist, но вам не нужно, чтобы проверить Bend.

поэтому, чтобы сделать это более четко, можно либо написать this->Twist показать читателю, что Twist является функцией-членом или написать ::Bend чтобы показать, что Bend бесплатно. Или обоих. Это очень полезно, когда вы находитесь выполнение или планирование рефакторинга.

:: - оператор определения пространства имен.

например, если вы хотите использовать cout без упоминания using namespace std; в коде вы пишете это:

std::cout << "test";

когда пространство имен не упоминается, что он сказал, что класс принадлежит к глобальному пространству имен.

Comments

    Ничего не найдено.