Molte risposte ragionevoli già. Chiederò un'analogia che potrebbe aiutare alcuni lettori. ::
funziona in modo molto simile al separatore di directory del filesystem ' /
', quando cerchi nel tuo percorso un programma che desideri eseguire. Prendere in considerazione:
/path/to/executable
Questo è molto esplicito: solo un eseguibile in quella posizione esatta nella struttura del filesystem può corrispondere a questa specifica, indipendentemente dal PERCORSO in vigore. Allo stesso modo ...
::std::cout
... è ugualmente esplicito nello spazio dei nomi C ++ "albero".
In contrasto con tali percorsi assoluti, è possibile configurare buone shell UNIX (ad es. Zsh ) per risolvere percorsi relativi nella directory corrente o qualsiasi elemento nella PATH
variabile di ambiente, quindi se PATH=/usr/bin:/usr/local/bin
, e si fosse "in" /tmp
, quindi ...
X11/xterm
... correrebbe felice /tmp/X11/xterm
se trovato, altro /usr/bin/X11/xterm
, altro /usr/local/bin/X11/xterm
. Allo stesso modo, supponiamo che tu fossi in uno spazio dei nomi chiamato X
e avessi un " using namespace Y
" attivo, quindi ...
std::cout
... potrebbe essere trovato in qualsiasi ::X::std::cout
, ::std::cout
, ::Y::std::cout
, ed eventualmente in altri luoghi a causa di ricerca argomento-dipendente (ADL, alias Koenig). Quindi, ::std::cout
è solo esplicito esattamente su quale oggetto intendi, ma per fortuna nessuno nella loro mente giusta creerebbe mai la propria classe / struttura o spazio dei nomi chiamato " std
", né qualsiasi cosa chiamata " cout
", quindi in pratica usare solo std::cout
va bene.
Differenze degne di nota :
1) le shell tendono a usare la prima corrispondenza usando l'ordinamento in PATH
, mentre C ++ dà un errore di compilatore quando sei stato ambiguo.
2) In C ++, i nomi senza alcun ambito iniziale possono essere abbinati nello spazio dei nomi corrente, mentre la maggior parte delle shell UNIX lo fa solo se si inserisce .
il file PATH
.
3) C ++ cerca sempre nello spazio dei nomi globale (come avere /
implicitamente il tuo PATH
).
Discussione generale su spazi dei nomi e spiegazione dei simboli
L'utilizzo di ::abc::def::...
"percorsi" assoluti a volte può essere utile per isolarti da qualsiasi altro spazio dei nomi che stai utilizzando, parte di ma in realtà non ha il controllo sul contenuto di, o anche altre librerie che utilizza anche il codice client della tua biblioteca. D'altra parte, ti abbina anche più strettamente alla posizione "assoluta" esistente del simbolo e perdi i vantaggi della corrispondenza implicita negli spazi dei nomi: meno accoppiamento, mobilità più semplice del codice tra spazi dei nomi e codice sorgente più conciso e leggibile .
Come per molte cose, è un atto di bilanciamento. I C ++ standard puts un sacco di identificatori ai sensi std::
che sono meno "unico" che cout
, che i programmatori possono utilizzare per qualcosa di completamente diverso nel loro codice (ad esempio merge
, includes
, fill
, generate
, exchange
, queue
, toupper
, max
). Due librerie non standard non correlate hanno una probabilità molto maggiore di utilizzare gli stessi identificatori degli autori che generalmente non sono consapevoli o meno consapevoli l'uno dell'altro. E le librerie - inclusa la libreria standard C ++ - cambiano i loro simboli nel tempo. Tutto ciò potenzialmente crea ambiguità quando si ricompila il vecchio codice, in particolare quando c'è stato un uso pesante di using namespace
s: la cosa peggiore che puoi fare in questo spazio è consentireusing namespace
è nelle intestazioni per sfuggire agli ambiti delle intestazioni, in modo tale che una quantità arbitrariamente grande di codice client diretto e indiretto non è in grado di prendere le proprie decisioni su quali spazi dei nomi usare e su come gestire le ambiguità.
Quindi, un leader ::
è uno strumento nella casella degli strumenti del programmatore C ++ per chiarire attivamente uno scontro noto e / o eliminare la possibilità di future ambiguità ....
::
significa riferimento alla variabile dallo spazio dei nomi globale / anonimo.