Jakie jest znaczenie dwukropka "::"?

Znalazłem ten wiersz kodu w klasie, którą muszę zmodyfikować:

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

I nie wiem, co dokładnie oznacza podwójny dwukropek poprzedzony nazwą klasy. Bez tego czytałbym: declaration of tmpCo jako wskaźnik do obiektu klasy Configuration... ale uprzedzona Podwójna okrężnica mnie myli.

Znalazłem też:

typedef ::config::set ConfigSet;
Author: emlai, 2010-11-24

8 answers

Zapewnia to, że rozdzielczość występuje z globalnej przestrzeni nazw, zamiast rozpoczynać się od przestrzeni nazw, w której aktualnie się znajdujesz. Na przykład, jeśli masz dwie różne klasy o nazwie Configuration jako takie:

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(...)
    }
}

Zasadniczo pozwala na przejście do globalnej przestrzeni nazw, ponieważ Twoja nazwa może zostać zablokowana przez nową definicję wewnątrz innej przestrzeni nazw, w tym przypadku MyApp.

 398
Author: Wyatt Anderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-24 16:27:38

Operator :: nazywa się operatorem scope-resolution i robi to właśnie, rozwiązuje zakres. Tak więc, poprzez prefiks nazwy typu z tym, mówi kompilator, aby szukać w globalnej przestrzeni nazw dla typu.

Przykład:

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;
}
 166
Author: Moo-Juice,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-24 16:27:16

Wiele rozsądnych odpowiedzi już. Dodam analogię, która może pomóc niektórym czytelnikom. :: działa podobnie jak separator katalogów systemu plików ' /' podczas wyszukiwania ścieżki dla programu, który chcesz uruchomić. Rozważyć:

/path/to/executable

Jest to bardzo jednoznaczne - tylko plik wykonywalny w tym samym miejscu w drzewie plików może pasować do tej specyfikacji, niezależnie od ścieżki. Podobnie...

::std::cout

... jest równie jawne w przestrzeni nazw C++ "drzewo".

W przeciwieństwie do takich ścieżek absolutnych, możesz skonfigurować dobre powłoki uniksowe (np. zsh), aby rozwiązywały ścieżki względne pod dowolnym elementem zmiennej środowiskowej PATH, więc jeśli PATH=/usr/bin:/usr/local/bin, to...

X11/xterm

...z chęcią uruchomi /usr/bin/X11/xterm jeśli zostanie znaleziony, else /usr/local/bin/X11/xterm. Podobnie, powiedzmy, że jesteś w przestrzeni nazw o nazwie X i masz "using namespace Y " w efekcie...

std::cout

...można znaleźć w każdym z ::X::std::cout, ::std::cout, ::Y::std::cout, i ewentualnie inne miejsca ze względu na wyszukiwanie zależne od argumentów (ADL, aka Koenig lookup). Tak więc tylko ::std::cout jest bardzo jasne co do tego, jaki dokładnie obiekt masz na myśli, ale na szczęście nikt przy zdrowych zmysłach nigdy nie stworzy własnej klasy/struktury lub przestrzeni nazw o nazwie " std", ani niczego o nazwie " cout", więc w praktyce używanie tylko std::cout jest w porządku.

(godna uwagi różnica polega na tym, że powłoki mają tendencję do używania pierwszego dopasowania przy użyciu kolejności w PATH, Podczas Gdy C++ daje błąd kompilatora, gdy niejednoznaczne.)

Ogólna dyskusja na temat przestrzeni nazw i jasności symboli

Używanie bezwzględnych ::abc::def::... "ścieżek" może być czasami przydatne, aby odizolować Cię od innych przestrzeni nazw, których używasz, które są częścią, ale tak naprawdę nie mają kontroli nad zawartością, a nawet innymi bibliotekami, których używa również kod klienta biblioteki. Z drugiej strony, to również paruje Cię bardziej ściśle do istniejącego "absolutnego" miejsca symbolu, i brakuje zalet ukrytego dopasowania w przestrzenie nazw: mniej sprzężeń, łatwiejsza mobilność kodu między przestrzeniami nazw i bardziej zwięzły, czytelny kod źródłowy.

Jak z wieloma rzeczami, jest to akt równoważenia. Standard C++ umieszcza wiele identyfikatorów pod std::, które są mniej "unikalne" niż cout, które programiści mogą używać do czegoś zupełnie innego w swoim kodzie (np. merge, includes, fill, generate, exchange, queue, toupper, max). Dwie niepowiązane biblioteki niestandardowe mają znacznie większą szansę na użycie tych samych identyfikatorów ponieważ autorzy są na ogół nie-lub mniej-świadomi siebie nawzajem. Biblioteki - w tym Biblioteka Standardowa C++ - zmieniają swoje symbole w czasie. Wszystko to potencjalnie tworzy niejednoznaczność podczas rekompilacji starego kodu, szczególnie w przypadku intensywnego użycia using namespace s: najgorszą rzeczą, jaką możesz zrobić w tej przestrzeni, jest pozwolenie using namespaceS w nagłówkach na ucieczkę z zakresu nagłówków, tak że arbitralnie duża ilość bezpośredniego i pośredniego kodu klienta nie jest w stanie podjąć własnych decyzji o tym, przestrzenie nazw do użycia i jak zarządzać niejednoznacznością.

Tak więc, wiodący :: jest jednym z narzędzi programisty C++ do aktywnego disambiguate znanego zderzenia, i / lub wyeliminować możliwość przyszłych niejasności....

 99
Author: Tony Delroy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-26 14:59:41

:: jest operatorem rozdzielczości zakresu. Służy do określenia zakresu czegoś.

Na przykład, :: jest obszarem globalnym, poza wszystkimi innymi przestrzeniami nazw.

some::thing może być interpretowany na jeden z następujących sposobów:

  • some jest przestrzenią nazw (w zasięgu globalnym lub zewnętrznym niż bieżący) i thing jest typem , funkcją , obiektem lub zagnieżdżoną przestrzenią nazw ;
  • some jest klasą dostępną w bieżącym zakresie, a thing jest obiektem składowym , function or type of the some class;
  • w funkcji członka klasy, some może być typem bazowym bieżącego typu (lub samego bieżącego typu) i thing jest wtedy jednym z członków tej klasy, A typem, funkcja lub obiekt.

Możesz również mieć zagnieżdżony zakres, jak w some::thing::bad. Tu każde imię może być Typ, obiekt lub Przestrzeń nazw. Ponadto ostatnia, bad, może być również funkcją. Inni nie mogą, ponieważ funkcje nie mogą ujawnić niczego w swoim wewnętrznym zakresie.

Wracając do twojego przykładu, ::thing może być tylko czymś w zasięgu globalnym: typem, funkcją, obiektem lub przestrzenią nazw.

Sposób, w jaki go używasz sugeruje (użyty w deklaracji wskaźnika), że jest to typ w globalnym zasięgu.

Mam nadzieję, że ta odpowiedź jest na tyle kompletna i poprawna, aby pomoże Ci zrozumieć rozdzielczość zakresu.

 32
Author: Klaim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-01 22:07:54

:: służy do łączenia czegoś (zmiennej, funkcji, klasy, typedef itp...) do przestrzeni nazw lub do klasy.

Jeśli nie ma lewej strony przed ::, to podkreśla fakt, że używasz globalnej przestrzeni nazw.

Np.:

::doMyGlobalFunction();

 12
Author: Stephane Rolland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-14 15:08:55

Jego nazywany operatorem rozdzielczości zakresu, ukryta globalna nazwa może być odwołana za pomocą operatora rozdzielczości zakresu:
Na przykład;

int x;
void f2()
{
   int x = 1; // hide global x
   ::x = 2; // assign to global x
   x = 2; // assign to local x
   // ...
}
 9
Author: Mustafa Ekici,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-11 17:59:10

(ta odpowiedź jest głównie dla googlerów, ponieważ OP już rozwiązał swój problem.) Znaczenie prepended :: - Scope resulution operator-zostało opisane w innych odpowiedziach, ale chciałbym dodać, dlaczego ludzie go używają.

Znaczenie to "weź nazwę z globalnej przestrzeni nazw, nie z niczego innego". Ale dlaczego miałoby to być wyraźnie napisane?

Use case-namespace clash

Gdy masz tę samą nazwę w globalnej przestrzeni nazw i w lokalnej / zagnieżdżonej przestrzeń nazw, zostanie użyta lokalna. Więc jeśli chcesz mieć globalną, dodaj ją ::. Ten przypadek został opisany w odpowiedzi @ Wyatt Anderson, plese zobacz jego przykład.

Use case-Funkcja nieczłonkowa

Kiedy piszesz funkcję członka (metodę), wywołania do innej funkcji członka i wywołania do innych (wolnych) funkcji wyglądają podobnie:

class A {
   void DoSomething() {
      m_counter=0;
      ...
      Twist(data); 
      ...
      Bend(data);
      ...
      if(m_counter>0) exit(0);
   }
   int m_couner;
   ...
}

Ale może się zdarzyć, że Twist jest siostrzaną funkcją klasy A, a {[5] } jest wolną funkcja. Oznacza to, że {[3] } może używać i modyfikować m_couner i Bend nie może. Więc jeśli chcesz mieć pewność, że m_counter pozostaje 0, musisz sprawdzić Twist, ale nie musisz sprawdzać Bend.

Aby to bardziej wyraźnie wyróżnić, można albo napisać this->Twist, aby pokazać czytelnikowi, że Twist jest funkcją członkowską, albo napisać ::Bend, aby pokazać, że Bend jest wolna. Albo jedno i drugie. Jest to bardzo przydatne, gdy robisz lub planujesz refaktoryzację.

 4
Author: Steed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-23 13:04:17

:: jest operatorem definiującym przestrzeń nazw.

Na przykład, jeśli chcesz użyć cout bez wspominania using namespace std; w kodzie napisz to:

std::cout << "test";

Gdy nie wspomniano o żadnej przestrzeni nazw, mówi się, że Klasa należy do globalnej przestrzeni nazw.

 3
Author: Vladimir Ivanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-24 16:26:11