464 votes

Quel est le sens de l'précédés de deux points "::" au nom de la classe?

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 d' tmpCo comme un pointeur vers un objet de la classe Configuration... mais la précédés de deux points me confond.

J'ai aussi trouvé:

typedef ::config::set ConfigSet;

551voto

Wyatt Anderson Points 4012

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:

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

Fondamentalement, il vous permet de parcourir 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.

212voto

Moo-Juice Points 22190

L' :: 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:

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;
}

135voto

Tony D Points 43962

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:

/path/to/executable

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...

::std::cout

...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 chemins d'accès en vertu de n'importe quel élément dans votre PATH variable d'environnement, donc si PATH=/usr/bin:/usr/local/bin, alors...

X11/xterm

...serait joyeusement /usr/bin/X11/xterm si trouvé, sinon, /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...

std::cout

...pourrait être trouvée dans l'une des ::X::std::cout, ::std::cout, ::Y::std::cout (et éventuellement d'autres endroits en raison de Koenig et la recherche des arguments). De la sorte, seuls ::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", donc, dans la pratique, en utilisant seulement std::cout est fine. Avec votre propre variables, cependant, que vous avez moins de garantie que d'autres personnes n'utilisent pas les mêmes noms, donc à l'aide des chemins absolus peut parfois être utile pour vous isoler de tous les autres espaces de noms que vous utilisez ou de la partie mais n'ont pas vraiment de contrôle sur le contenu de. D'autre part, il a également des couples vous plus étroitement à l'existant "absolue" de l'emplacement du symbole, qui va à l'encontre de l'un des avantages des espaces de noms dans le fait d'avoir moins de couplage et implicites de correspondance.

43voto

Klaim Points 24511

:: 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, de tous les espaces de noms.

some::thing peuvent être :

  • some est un espace de noms (dans le contexte global, ou à l'extérieur de la portée de celui en cours) et thing est un type, une fonction, un objet ou un espace de noms imbriqué;
  • some est une classe disponible dans le courant de la portée et de l' thing est un membre de l'objet, la fonction ou le type de l' some de la classe;
  • dans une fonction membre de classe, some peut être un type de base du type de courant (ou le type), et thing est un membre de cette classe, le type, la fonction ou l' objet.

Vous pouvez également avoir imbriqués portée comme some::thing::bad. Ici, chaque nom peut être d'un type, d'un objet ou d'un espace de noms. Seulement bad pourrait également être une fonction comme la fonction ne peut pas exposer 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èrent (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 complète et correcte assez pour comprendre la portée de la résolution.

10voto

Mustafa Ekici Points 2879

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;

int x;
void f2()
{
   int x = 1; // hide global x
   ::x = 2; // assign to global x
   x = 2; // assign to local x
   // ...
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X