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