J'ai trouvé cette ligne de code dans une classe que je dois modifier:
::Configuration * tmpCo = m_configurationDB;//pointer to current db
et je ne sais pas ce que signifie exactement le double deux-points ajouté au nom de la classe. Sans cela, je lirais: déclaration de tmpCo
comme pointeur sur un objet de la classe Configuration
... mais le double deux points ajouté me confond.
J'ai aussi trouvé:
typedef ::config::set ConfigSet;
c++
syntax
namespaces
scope-resolution
global-namespace
rmbianchi
la source
la source
::
moyens nus référencent la variable de l'espace de noms global / anonyme.Réponses:
Cela garantit que la résolution se produit à partir de l'espace de noms global, au lieu de commencer à l'espace de noms dans lequel vous vous trouvez actuellement. Par exemple, si vous aviez deux classes différentes appelées
Configuration
comme telles:Fondamentalement, il vous permet de parcourir jusqu'à l'espace de noms global car votre nom peut être assailli par une nouvelle définition dans un autre espace de noms, dans ce cas
MyApp
.la source
::Configuration::doStuff(...)
::
deux termes intermédiaires se réfèrent à l'espace de noms ou à la classe et à son membre. Mais qu'en est-il du 1er?L'
::
opérateur est appelé opérateur de résolution de portée et fait exactement cela, il résout la portée. Ainsi, en préfixant un nom de type avec ceci, il indique à votre compilateur de rechercher dans le nom global le type.Exemple:
la source
Beaucoup de réponses raisonnables déjà. Je vais apporter une analogie qui pourrait aider certains lecteurs.
::
fonctionne un peu comme le séparateur de répertoires du système de fichiers '/
', lorsque vous recherchez dans votre chemin un programme que vous souhaitez exécuter. Considérer:Ceci est très explicite - seul un exécutable à cet emplacement exact dans l'arborescence du système de fichiers peut correspondre à cette spécification, quel que soit le PATH en vigueur. De même...
... est également explicite dans "l'arborescence" de l'espace de noms C ++.
Contrairement à ces chemins absolus, vous pouvez configurer de bons shells UNIX (par exemple zsh ) pour résoudre les chemins relatifs sous votre répertoire actuel ou n'importe quel élément de votre
PATH
variable d'environnement, donc siPATH=/usr/bin:/usr/local/bin
, et vous étiez "dans"/tmp
, alors ...... courrait avec plaisir
/tmp/X11/xterm
s'il était trouvé, sinon/usr/bin/X11/xterm
, sinon/usr/local/bin/X11/xterm
. De même, supposons que vous vous trouviez dans un espace de noms appeléX
, et que vous aviez un "using namespace Y
" en vigueur, alors ...... pourrait être trouvé dans l' un des
::X::std::cout
,::std::cout
,::Y::std::cout
et éventuellement d' autres endroits en raison de recherche dépendant de l' argument (ADL, alias Koenig recherche). Donc, seul::std::cout
est vraiment explicite exactement l'objet que vous voulez dire, mais heureusement, personne sensé ne créerait jamais sa propre classe / structure ou espace de noms appelé "std
", ni quoi que ce soit appelé "cout
", donc en pratique, utiliserstd::cout
est très bien.Différences notables :
1) les shells ont tendance à utiliser la première correspondance en utilisant l'ordre dans
PATH
, tandis que C ++ donne une erreur de compilation lorsque vous avez été ambigu.2) En C ++, les noms sans portée principale peuvent être mis en correspondance dans l'espace de noms actuel, tandis que la plupart des shells UNIX ne le font que si vous les mettez
.
dans lePATH
.3) C ++ recherche toujours l'espace de noms global (comme avoir
/
implicitement votrePATH
).Discussion générale sur les espaces de noms et l'explicitation des symboles
L'utilisation de
::abc::def::...
"chemins" absolus peut parfois être utile pour vous isoler de tout autre espace de noms que vous utilisez, qui fait partie, mais n'a pas vraiment de contrôle sur le contenu, ni même d'autres bibliothèques que le code client de votre bibliothèque utilise également. D'autre part, il vous couple également plus étroitement à l'emplacement "absolu" existant du symbole, et vous manquez les avantages de la correspondance implicite dans les espaces de noms: moins de couplage, mobilité plus facile du code entre les espaces de noms et code source plus concis et lisible .Comme pour beaucoup de choses, c'est un équilibre. Les C ++ standard puts beaucoup d'identificateurs sous
std::
qui sont moins « unique » quecout
, que les programmeurs peuvent utiliser pour quelque chose de complètement différent dans leur code (par exemplemerge
,includes
,fill
,generate
,exchange
,queue
,toupper
,max
). Deux bibliothèques non standard non apparentées ont beaucoup plus de chances d'utiliser les mêmes identifiants car les auteurs ne se connaissent généralement pas ou moins. Et les bibliothèques - y compris la bibliothèque C ++ Standard - changent leurs symboles au fil du temps. Tout cela crée potentiellement une ambiguïté lors de la recompilation de l'ancien code, en particulier lorsqu'il y a eu une utilisation intensive deusing namespace
s: la pire chose que vous puissiez faire dans cet espace est de permettreusing namespace
s dans les en-têtes pour échapper à la portée des en-têtes, de sorte qu'une quantité arbitrairement importante de code client direct et indirect ne peut pas prendre ses propres décisions concernant les espaces de noms à utiliser et comment gérer les ambiguïtés.Ainsi, un leader
::
est un outil dans la boîte à outils du programmeur C ++ pour lever activement l'ambiguïté d'un conflit connu et / ou éliminer la possibilité d'une ambiguïté future ...la source
::
est l'opérateur de résolution de la portée. Il est utilisé pour spécifier la portée de quelque chose.Par exemple,
::
seule est la portée globale, en dehors de tous les autres espaces de noms.some::thing
peut être interprété de l'une des manières suivantes:some
est un espace de noms (dans la portée globale ou une portée extérieure à la portée actuelle) etthing
est un type , une fonction , un objet ou un espace de noms imbriqué ;some
est une classe disponible dans la portée actuelle etthing
est un objet membre , une fonction ou un type de lasome
classe;some
peut être un type de base du type actuel (ou le type actuel lui-même) etthing
est alors un membre de cette classe, un type , une fonction ou un objet .Vous pouvez également avoir une portée imbriquée, comme dans
some::thing::bad
. Ici, chaque nom peut être un type, un objet ou un espace de noms. De plus, le dernier,,bad
pourrait également être une fonction. Les autres ne pouvaient pas, car les fonctions ne peuvent rien exposer dans leur portée interne.Donc, revenons à votre exemple,
::thing
ne peut être que quelque chose dans la portée globale: un type, une fonction, un objet ou un espace de noms.La façon dont vous l'utilisez suggère (utilisé dans une déclaration de pointeur) qu'il s'agit d'un type dans la portée globale.
J'espère que cette réponse est complète et suffisamment correcte pour vous aider à comprendre la résolution de la portée.
la source
class some { protected: int thing; }; class some_ext : public some { float thing; void action(){ some::thing = 42; thing = 666; } };
Voicisome
une classe de base desome_ext
et lorsque vous écrivezsome::thing
dans les fonctions membres de some_ext, cela signifie l'thing
objet dans le type de basesome
. Sanssome::
,thing
seul signifie lething
plus proche, c'est-à-diresome_ext::thing
. Est-ce plus clair?::
est utilisé pour lier quelque chose (une variable, une fonction, une classe, un typedef etc ...) à un espace de noms, ou à une classe.s'il n'y a pas de gauche avant
::
, cela souligne le fait que vous utilisez l'espace de noms global.par exemple:
::doMyGlobalFunction();
la source
son opérateur de résolution de portée appelé, Un nom global caché peut être référencé en utilisant l'opérateur de résolution de portée ::
Par exemple;
la source
(Cette réponse s'adresse principalement aux googleurs, car OP a déjà résolu son problème.)
::
opérateur de résolution de portée ajouté a été décrit dans d'autres réponses, mais j'aimerais ajouter pourquoi les gens l'utilisent.La signification est "prendre le nom de l'espace de noms global, pas autre chose". Mais pourquoi cela devrait-il être orthographié explicitement?
Cas d'utilisation - conflit d'espace de noms
Lorsque vous avez le même nom dans l'espace de noms global et dans l'espace de noms local / imbriqué, le nom local sera utilisé. Donc, si vous voulez le global, ajoutez-le avec
::
. Ce cas a été décrit dans la réponse de @Wyatt Anderson, veuillez voir son exemple.Cas d'utilisation - souligner la fonction non membre
Lorsque vous écrivez une fonction membre (une méthode), les appels à une autre fonction membre et les appels à des fonctions non membres (gratuites) se ressemblent:
Mais il peut arriver que ce
Twist
soit une fonction membre de classe sœurA
, etBend
soit une fonction libre. Autrement dit,Twist
peut utiliser et modifierm_couner
etBend
ne peut pas. Donc, si vous voulez vous assurer quem_counter
reste 0, vous devez vérifierTwist
, mais vous n'avez pas besoin de vérifierBend
.Donc, pour que cela ressorte plus clairement, on peut soit écrire
this->Twist
pour montrer au lecteur quiTwist
est une fonction membre, soit écrire::Bend
pour montrer queBend
c'est gratuit. Ou les deux. Ceci est très utile lorsque vous effectuez ou planifiez une refactorisation.la source
::
est un opérateur de définition de l'espace de noms.Par exemple, si vous souhaitez utiliser cout sans mentionner
using namespace std;
dans votre code, vous écrivez ceci:Quand aucun espace de noms n'est mentionné, il est dit que la classe appartient à l'espace de noms global.
la source
"::" représente l'opérateur de résolution de portée. Les fonctions / méthodes qui portent le même nom peuvent être définies dans deux classes différentes. Pour accéder aux méthodes d'un opérateur de résolution d'étendue de classe particulier est utilisé.
la source