Quel est le sens de l'précédés de deux points “::”?
J'ai trouvé cette ligne de code dans une classe que j'ai modifier:
::Configuration * tmpCo = m_configurationDB;//pointer to current db
et je ne sais pas ce que signifie exactement le double du côlon préfixer le nom de la classe. Sans que je pourrais lire: déclaration de tmpCo
comme un pointeur vers un objet de la classe Configuration
... mais le précédés de deux points me confond.
J'ai aussi trouvé:
typedef ::config::set ConfigSet;
- Ne pas vraiment se sentir qu'il est une réponse, donc je vais commentaire: en.wikipedia.org/wiki/Scope_resolution_operator. Dans ce contexte, le nu
::
moyens de référence de la variable à partir du global/anonyme de l'espace de noms.
Vous devez vous connecter pour publier un commentaire.
Cela garantit que la résolution se produit à partir de l'espace de noms global, au lieu de partir de l'espace de noms, vous êtes actuellement dans. Par exemple, si vous avez deux différentes classes de
Configuration
en tant que tel:Fondamentalement, il permet de traverser jusqu'à l'espace de noms global puisque votre nom pourrait obtenir assommé par une nouvelle définition à l'intérieur d'un autre espace de noms, dans ce cas
MyApp
.::Configuration::doStuff(...)
::
entre les deux termes se réfère à l'espace de noms ou de la classe et de ses membres. Mais ce que sur le 1er?La
::
opérateur est appelé le champ d'application-opérateur de résolution et s'y tient, il décide de la portée. Donc, en préfixant un type de nom, l'indique au compilateur de regarder dans l'espace de noms global pour le type.Exemple:
Beaucoup de raisonnable réponses déjà. Je vais puce avec une analogie qui peut aider certains lecteurs.
::
fonctionne un peu comme le système de fichiers séparateur de répertoire '/
', lors de la recherche de votre chemin pour un programme que vous voulez exécuter. Considérer:C'est très explicite - seulement un exécutable au même emplacement dans l'arborescence du système de fichiers peut correspondre à cette spécification, quel que soit le CHEMIN d'accès en vigueur. De la même manière...
...est tout aussi explicite dans le C++ de l'espace de noms "arbre".
Contrastant avec ces chemins absolus, vous pouvez configurer bonne shells UNIX (par exemple,zsh) pour résoudre relative sentiers dans votre répertoire courant (ou de n'importe quel élément dans votre
PATH
variable d'environnement, donc siPATH=/usr/bin:/usr/local/bin
, et vous avez été "dans"/tmp
, alors......ferait un plaisir de les exécuter
/tmp/X11/xterm
si trouvé, d'autre/usr/bin/X11/xterm
, d'autre/usr/local/bin/X11/xterm
. De même, dire que vous étiez dans un espace de noms appeléX
, et a eu un "using namespace Y
" en effet, alors......pourrait être trouvée dans l'une des
::X::std::cout
,::std::cout
,::Y::std::cout
, et peut-être d'autres endroits en raison de argument dépendant de recherche (ADL, aka Koenig de recherche). Ainsi, seule la::std::cout
est vraiment explicite sur exactement l'objet que vous voulez dire, mais heureusement, personne dans leur bon esprit jamais créer leur propre class/struct ou de l'espace appelé "std
", ni quoi que ce soit appelé "cout
", de sorte que, dans la pratique, en utilisant uniquementstd::cout
est fine.Des différences notables entre:
1) des coquilles ont tendance à utiliser le premier match à l'aide de la commande dans
PATH
, alors que C++ donne une erreur de compilation lorsque vous avez été ambiguë.2) En C++, les noms sans grande envergure peut être mis en correspondance dans l'espace de noms courant, alors que la plupart des shells UNIX seulement que si vous mettez
.
dans lePATH
.3) C++ toujours à la recherche dans l'espace de noms global (comme d'avoir
/
implicitement votrePATH
).Discussion générale sur les espaces de noms et de caractère explicite de symboles
À l'aide absolu
::abc::def::...
"chemins d'accès" peut parfois être utile pour vous isoler de tous les autres espaces de noms que vous utilisez, de la partie mais n'ont pas vraiment de contrôle sur le contenu, ni même les autres bibliothèques de votre bibliothèque de code client utilise aussi les. D'autre part, il a également des couples vous plus étroitement à l'existant "absolue" de l'emplacement du symbole, et vous manquez les avantages de l'implicite correspondant à des espaces de noms: moins d'attelage, de faciliter la mobilité de code entre les espaces de noms, et plus concis, lisible de la source code.Comme pour beaucoup de choses, c'est un acte d'équilibrage. La Norme C++ met beaucoup d'identificateurs de sous
std::
qui sont moins "unique" quecout
, que les programmeurs peuvent utiliser pour quelque chose de complètement différent dans leur code (par ex.merge
,includes
,fill
,generate
,exchange
,queue
,toupper
,max
). Deux non-Standard des bibliothèques ont nettement plus de chance d'utiliser les mêmes identifiants que les auteurs sont en général des nations unies - ou moins-connaissance les uns des autres. Et les bibliothèques - y compris le C++ Standard library - changement de leurs symboles au fil du temps. Tout cela crée potentiellement toute ambiguïté lors de la recompilation de l'ancien code, en particulier quand il y a eu une forte utilisation deusing namespace
s: la pire chose que vous pouvez faire dans, cet espace est de permettreusing namespace
s dans les en-têtes pour échapper à la les en-têtes' étendues, telles qu'un nombre arbitrairement grand de directs et indirects code du client est incapable de prendre leurs propres décisions au sujet de laquelle les espaces de noms à utiliser et la façon de gérer les ambiguïtés.Ainsi, l'un des principaux
::
est un outil dans le programmeur C++ boîte à outils activement à lever l'ambiguïté connu clash, et/ou d'éliminer la possibilité de l'avenir de l'ambiguïté....::
est l'opérateur de résolution de portée. Il est utilisé pour spécifier la portée de quelque chose.Par exemple,
::
seul est la portée globale, en dehors de tous les autres espaces de noms.some::thing
peut être interprété de bien des manières suivantes:some
est un espace de noms (dans le contexte global, ou à l'extérieur de la portée de celui en cours) etthing
est un type, un fonction, un objet ou un imbriquée à l'espace de noms;some
est un classe disponibles dans ce domaine etthing
est un objet membre, fonction ou type de lasome
classe;some
peut être un type de base du type de courant (ou le type de courant lui-même) etthing
est un membre de cette classe, un type, fonction ou objet.Vous pouvez également avoir imbriqués portée, comme dans
some::thing::bad
. Ici, chaque nom peut être d'un type, d'un objet ou d'un espace de noms. En outre, la dernière,bad
, pourrait également être une fonction. Les autres ne peuvent pas, car les fonctions ne peut pas exposer quelque chose à l'intérieur de leur portée interne.Donc, retour à votre exemple,
::thing
peut être que quelque chose dans l'étendue globale: un type, d'une fonction, d'un objet ou d'un espace de noms.La façon dont vous l'utilisez suggère (utilisé dans une déclaration de pointeur) que c'est un type dans la portée globale.
J'espère que cette réponse est complet et suffisamment correct pour vous aider à comprendre la portée de la résolution.
class some { protected: int thing; }; class some_ext : public some { float thing; void action(){ some::thing = 42; thing = 666; } };
Icisome
est une classe de base desome_ext
et quand vous écrivezsome::thing
dans les fonctions de membres de some_ext, cela signifie que lething
objet dans le type de basesome
. Sanssome::
,thing
seul moyen de lathing
dans la portée la plus proche, c'est-àsome_ext::thing
. Est-il plus clair?::
est utilisée pour lier quelque chose ( une variable, une fonction, une classe, un typedef, etc...) à un espace de noms, ou à une classe.si il n'y a pas de gauche avant d'
::
, puis il insiste sur le fait que vous utilisez l'espace de noms global.par exemple:
::doMyGlobalFunction();
son appelé opérateur de résolution de portée, Une face cachée de nom global peut être appelée à l'aide de l'opérateur de résolution de portée ::
Par exemple;
(Cette réponse est la plupart du temps pour les googlers, parce que l'OP a résolu son problème déjà.)
Le sens de préfixé
::
- portée resulution opérateur a été décrit dans d'autres réponses, mais je voudrais ajouter pourquoi les gens sont à l'utiliser.Le sens est "prendre le nom d'espace de noms global, pas autre chose". Mais pourquoi ce besoin d'être orthographié de façon explicite?
Cas d'utilisation de l'espace de noms clash
Lorsque vous avez le même nom dans l'espace de noms global et local/espace de noms imbriqué, les locaux seront utilisés. Donc, si vous voulez la mondiale, le préfixer avec
::
. Ce cas a été décrit dans @Wyatt Anderson réponse, s'il vous plait voir son exemple.Cas d'utilisation - insister sur la non-membre de la fonction
Lorsque vous écrivez une fonction membre (une méthode), les appels vers les autres membres de la fonction et des appels à la non-membre (gratuit) fonctions ressemblent:
Mais il peut arriver que
Twist
est une sœur de la fonction membre de la classeA
, etBend
est une fonction libre. C'est,Twist
pouvez 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
.Pour faire ressortir plus clairement, on peut soit écrire
this->Twist
montrer au lecteur queTwist
est une fonction membre ou écrire::Bend
pour montrer queBend
est gratuit. Ou les deux. Ceci est très utile lorsque vous faites des ou la planification d'un refactoring.::
est un opérateur de définir l'espace de noms.Par exemple, si vous souhaitez utiliser cout sans mentionner
using namespace std;
dans votre code que vous écrivez ceci:Lorsque aucun espace de noms n'est mentionné, qu'il est dit que la classe appartient à l'espace de noms global.
"::" représente l'opérateur de résolution de portée.
Fonctions/méthodes qui ont le même nom peut être défini de deux classes différentes. Pour accéder aux méthodes d'une classe particulière opérateur de résolution de portée est utilisé.