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: deklaracja tmpCo
jako wskaźnik do obiektu klasy Configuration
... ale poprzedzony podwójny dwukropek myli mnie.
Znalazłem też:
typedef ::config::set ConfigSet;
c++
syntax
namespaces
scope-resolution
global-namespace
rmbianchi
źródło
źródło
::
oznacza odwołanie do zmiennej z globalnej / anonimowej przestrzeni nazw.Odpowiedzi:
Zapewnia to, że rozpoznawanie odbywa się z globalnej przestrzeni nazw, zamiast zaczynać od przestrzeni nazw, w której się obecnie znajdujesz. Na przykład, jeśli masz dwie różne klasy nazywane
Configuration
jako takie:Zasadniczo umożliwia przejście do globalnej przestrzeni nazw, ponieważ w tym przypadku twoje imię może zostać zablokowane przez nową definicję w innej przestrzeni nazw
MyApp
.źródło
::Configuration::doStuff(...)
::
dwa terminy odnoszą się do przestrzeni nazw lub klasy i jej członka. Ale co z pierwszym?::
Operator nazywa operator zakres rozdzielczości i właśnie to robi, to rozwiązuje zakres. Tak więc, poprzedzając to nazwą typu, informuje kompilator, aby szukał w globalnej przestrzeni nazw dla typu.Przykład:
źródło
Wiele rozsądnych odpowiedzi już. Wprowadzę analogię, która może pomóc niektórym czytelnikom.
::
działa bardzo podobnie do separatora katalogów systemu plików '/
' podczas wyszukiwania ścieżki w poszukiwaniu programu, który chcesz uruchomić. Rozważać:Jest to bardzo wyraźne - tylko plik wykonywalny w tej dokładnej lokalizacji w drzewie systemu plików może pasować do tej specyfikacji, niezależnie od obowiązującej PATH. Podobnie...
... jest równie wyraźne w „drzewie” przestrzeni nazw C ++.
Kontrastując z takimi ścieżkami bezwzględnymi, możesz skonfigurować dobre powłoki UNIX (np. Zsh ), aby rozpoznawać ścieżki względne w bieżącym katalogu lub dowolnym elemencie
PATH
zmiennej środowiskowej, więc jeśliPATH=/usr/bin:/usr/local/bin
i byłeś „w”/tmp
, to ...... z radością uciekłby,
/tmp/X11/xterm
gdyby został znaleziony/usr/bin/X11/xterm
, inaczej/usr/local/bin/X11/xterm
. Podobnie, powiedz, że byłeś w przestrzeni nazwanejX
i miałeśusing namespace Y
efekt „ ”, a następnie ...... można znaleźć w każdym z
::X::std::cout
,::std::cout
,::Y::std::cout
i ewentualnie innych miejsc ze względu na odnośnika argumentu zależne (ADL, aka Koenig odnośników). Tak więc, tylko::std::cout
jest naprawdę jasne, co dokładnie masz na myśli, ale na szczęście nikt przy zdrowych zmysłach nigdy nie stworzyłby własnej klasy / struktury lub przestrzeni nazw o nazwie „std
”, ani niczego zwanego „cout
”, więc w praktyce używanie tylkostd::cout
jest w porządku.Godne uwagi różnice :
1) powłoki zwykle używają pierwszego dopasowania przy użyciu kolejności
PATH
, podczas gdy C ++ daje błąd kompilatora, gdy jesteś niejednoznaczny.2) W C ++, nazwy bez jakiejkolwiek prowadzącej zakresie mogą być dopasowane w bieżącym obszarze nazw, podczas gdy większość muszle UNIX zrobić tylko, że jeśli umieścić
.
wPATH
.3) C ++ zawsze przeszukuje globalną przestrzeń nazw (np.
/
Pośrednio twojąPATH
).Ogólna dyskusja na temat przestrzeni nazw i jawności symboli
Używanie absolutnych
::abc::def::...
„ścieżek” może czasem być przydatne do odizolowania cię od innych używanych przestrzeni nazw, które są częścią, ale tak naprawdę nie mają kontroli nad zawartością, a nawet innymi bibliotekami, z których korzysta także kod klienta twojej biblioteki. Z drugiej strony, bardziej ciasno łączy się z istniejącą „bezwzględną” lokalizacją symbolu i brakuje ci zalet niejawnego dopasowywania w przestrzeniach nazw: mniej sprzężenia, łatwiejsza mobilność kodu między przestrzeniami nazw i bardziej zwięzły, czytelny kod źródłowy .Jak w przypadku wielu rzeczy, jest to działanie równoważące. C ++ standard stawia wiele identyfikatorów pod
std::
które są mniej „unikalne” niżcout
, że programiści mogą wykorzystać na coś zupełnie innego w kodzie (npmerge
,includes
,fill
,generate
,exchange
,queue
,toupper
,max
). Dwie niepowiązane niestandardowe biblioteki mają znacznie większą szansę na użycie tych samych identyfikatorów, ponieważ autorzy są na ogół nieświadomi siebie nawzajem lub mniej. A biblioteki - w tym biblioteka C ++ Standard - z czasem zmieniają swoje symbole. Wszystko to potencjalnie tworzy dwuznaczność podczas ponownej kompilacji starego kodu, szczególnie gdy często używa sięusing namespace
s: najgorszą rzeczą, jaką możesz zrobić w tym miejscu, jest zezwolenieusing namespace
w nagłówkach, aby uciec przed zasięgami nagłówków, tak że arbitralnie duża ilość bezpośredniego i pośredniego kodu klienta nie jest w stanie podejmować własnych decyzji, których przestrzeni nazw użyć i jak zarządzać niejednoznacznościami.Tak więc wiodącym
::
jest jedno narzędzie w zestawie narzędzi programisty C ++, które aktywnie ujednoznacznia znane zderzenie i / lub eliminuje możliwość niejasności w przyszłości ...źródło
::
jest operatorem rozdzielczości zakresu. Służy do określania zakresu czegoś.Na przykład
::
sam jest zasięgiem globalnym, poza wszystkimi innymi przestrzeniami nazw.some::thing
można interpretować na jeden z następujących sposobów:some
jest przestrzenią nazw (w zakresie globalnym lub zewnętrznym niż bieżący) ithing
jest typem , funkcją , obiektem lub zagnieżdżoną przestrzenią nazw ;some
jest klasa dostępne w aktualnym zakresie ithing
jest przedmiotem element , działanie lub typu zsome
klasy;some
może być typem podstawowym bieżącego typu (lub samego bieżącego typu), athing
następnie jest jednym członkiem tej klasy, typem , funkcją lub obiektem .Możesz także mieć zakres zagnieżdżony, jak w
some::thing::bad
. Tutaj każda nazwa może być typem, obiektem lub przestrzenią nazw. Ponadto ostatnibad
, może również być funkcją. Inne nie mogły, ponieważ funkcje nie mogą ujawnić niczego w swoim wewnętrznym zakresie.Wracając do twojego przykładu,
::thing
może być tylko czymś w zakresie globalnym: typ, funkcja, obiekt lub przestrzeń nazw.Sposób użycia sugeruje (używany w deklaracji wskaźnika), że jest to typ w zakresie globalnym.
Mam nadzieję, że ta odpowiedź jest kompletna i wystarczająco poprawna, aby pomóc Ci zrozumieć rozdzielczość zakresu.
źródło
class some { protected: int thing; }; class some_ext : public some { float thing; void action(){ some::thing = 42; thing = 666; } };
Otosome
podstawowa klasa,some_ext
a kiedy piszeszsome::thing
do funkcji składowych some_ext, oznacza tothing
obiekt w typie podstawowymsome
. Bezsome::
,thing
sam oznacza tothing
w najbliższym zakresie, to znaczysome_ext::thing
. Czy to jest bardziej jasne?::
służy do łączenia czegoś (zmiennej, funkcji, klasy, typedef itp.) z przestrzenią nazw lub klasą.jeśli wcześniej nie było lewej strony
::
, oznacza to, że używasz globalnej przestrzeni nazw.na przykład:
::doMyGlobalFunction();
źródło
zwany operatorem rozpoznawania zakresu, do ukrytej nazwy globalnej można się odwoływać za pomocą operatora rozpoznawania zakresu:
na przykład;
źródło
(Ta odpowiedź jest głównie dla pracowników Google, ponieważ OP już rozwiązał swój problem.) Znaczenie wcześniejszego
::
- operator resulution zakresu - zostało opisane w innych odpowiedziach, ale chciałbym dodać, dlaczego ludzie go używają.Oznacza to: „weź nazwę z globalnej przestrzeni nazw, a nie cokolwiek innego”. Ale dlaczego miałoby to być wyrażone wprost?
Używaj kolizji nazw i nazw
Jeśli masz taką samą nazwę w globalnej przestrzeni nazw i w lokalnej / zagnieżdżonej przestrzeni nazw, używana będzie lokalna. Więc jeśli chcesz globalny, dodaj go
::
. Ten przypadek został opisany w odpowiedzi @Wyatt Anderson, proszę zobaczyć jego przykład.Przypadek użycia - podkreśl funkcję nie będącą członkiem
Kiedy piszesz funkcję członka (metodę), wywołania innej funkcji członka i wywołania funkcji nie będących członkami (bezpłatnych) wyglądają podobnie:
Ale może się zdarzyć, że
Twist
jest to siostrzana funkcja klasyA
iBend
jest funkcją bezpłatną. Oznacza to, żeTwist
można używać i modyfikować,m_couner
aBend
nie można. Więc jeśli chcesz upewnić się, żem_counter
pozostaje 0, musisz to sprawdzićTwist
, ale nie musisz tego sprawdzaćBend
.Aby wyrazić to wyraźniej, można albo napisać,
this->Twist
aby wskazać czytelnikowi, któryTwist
jest funkcją składową, albo napisać,::Bend
aby pokazać, żeBend
jest wolny. Lub obie. Jest to bardzo przydatne, gdy robisz lub planujesz refaktoryzację.źródło
::
jest operatorem definiującym przestrzeń nazw.Na przykład, jeśli chcesz użyć cout bez wzmianki
using namespace std;
w kodzie, napisz:Gdy nie wspomniano o przestrzeni nazw, mówi się, że klasa należy do globalnej przestrzeni nazw.
źródło
„::” reprezentuje operator rozdzielczości zakresu. Funkcje / metody o tej samej nazwie można zdefiniować w dwóch różnych klasach. Aby uzyskać dostęp do metod określonego zakresu klasy, używany jest operator rozdzielczości.
źródło