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