Что означает добавленное двойное двоеточие "::"?
Я нашел эту строку кода в класс, который я должен изменить:
::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.
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