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

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

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

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

Я нашел:

typedef ::config::set ConfigSet;

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.


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

пример:

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 затем один из членов этого класса тип, функции или объект.

вы также можете иметь вложенную область, как в 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
   // ...
}

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

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

использовать case-пространство имен clash

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

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

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

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 является функцией-членом или write ::Bend чтобы показать, что Bend бесплатно. Или обоих. Это очень полезно, когда вы выполнение или планирование рефакторинга.


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

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

std::cout << "test";

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