Pourquoi est-ce que C++ besoin de l'opérateur de résolution de portée?
(Je sais ce que l'opérateur de résolution de portée, et quand et comment l'utiliser).
Pourquoi est-ce que C++ ont la ::
opérateur, au lieu d'utiliser le .
exploitant à cette fin? Java n'est pas séparé de l'opérateur, et fonctionne très bien. Est-il une différence entre C++ et Java qui signifie C++ nécessite un opérateur, afin d'être analysée?
Ma conjecture est que ::
est nécessaire pour des raisons de préséance, mais je ne vois pas pourquoi il doit avoir une priorité plus élevée que, par exemple, .
. La situation que je peux penser est donc que quelque chose comme
a.b::c;
serait analysée comme
a.(b::c);
mais je ne peux pas penser à une situation dans laquelle la syntaxe comme ce serait possible de le faire de toute façon.
Peut-être que c'est juste une affaire de "ils font des choses différentes, de sorte qu'ils pourraient ainsi un aspect différent". Mais cela n'explique pas pourquoi ::
a une priorité plus élevée que .
.
OriginalL'auteur Karu | 2012-02-18
Vous devez vous connecter pour publier un commentaire.
Pourquoi C++ n'est pas l'utilisation
.
où il utilise::
, c'est parce que c'est la façon dont la langue est définie. Une raison plausible pourrait être, pour faire référence à l'espace de noms global à l'aide de la syntaxe::a
comme indiqué ci-dessous:Démo En Ligne
Je ne sais pas comment Java résout ce problème. Je ne sais même pas si en Java, il est l'espace de noms global. En C#, vous vous référez au nom global à l'aide de la syntaxe
global::a
, ce qui signifie encore C# a::
opérateur.Qui a dit que la syntaxe comme
a.b::c
n'est pas légal?Tenir compte de ces classes:
Maintenant voir ceci (ideone):
b.f()
ne peut pas être appelé comme ça, comme la fonction est cachée, et le CCG donne ce message d'erreur:Afin d'appeler
b.f()
(ou plutôtA::f()
), vous devez opérateur de résolution de portée:Démo à ideone
b.A.f
au lieu deb.A::f
. SiA
est un nom au lieu d'une variable ou d'une fonction, puis à l'aide de.
pourrait facilement direscope resolution
au lieu de l'ordinaire de sens.Mise à jour de réponse.
Peut-être, mais si vous aviez été à la recherche à elle pendant 10 ans, il ne serait pas. Personnellement,
::
semble plus difficile, même après 10 ans.L'hypothèse que j'ai fait sur
a.b::c
ne pas être sensible est ce qui causait ma confusion. Accepté cette réponse parce que je pense que c'est aussi bon que les autres, mais aussi de ma faute.Il n'y a pas d'espace de noms global en Java, car tout est à l'intérieur d'une classe ou d'une autre.
OriginalL'auteur Nawaz
Parce que quelqu'un dans le C++ comité des normes de la pensée que c'était une bonne idée pour permettre à ce code fonctionne:
Fondamentalement, il permet à un membre de la variable et une classe dérivée de type à avoir le même nom. J'ai aucune idée de ce que quelqu'un était en train de fumer quand ils ont pensé que c'était important. Mais il est là.
Lorsque le compilateur voit
.
, il sait que la chose à la gauche doit être un objet. Quand il voit::
, il doit être un nom ou un espace de noms (ou rien, indiquant l'espace de noms global). C'est sa façon de résoudre cette ambiguïté.test.foo.blah = 10
? Outest.base.blah = 10
oùbase
est un mot-clé?Parce que l'introduction d'un mot-clé est un beaucoup de plus difficile que de l'introduction d'un opérateur. Et
test.foo.blah
est ambigu; c'est la classe de base deblah
ou lathingy
membre dublah
? Java (que je comprends) permet de contourner ce fait en disant que c'est toujours le membre; vous ne pouvez l'obtenir à la base de la classe des variables membres par le casting du type.Parce que cela ne ferait pas de moyen de spécifier
base
vous vouliez l'utiliser.Il peut-être plus difficile de compilateur point de vue de l'auteur, mais à partir de programmeurs point de vue
base.blah
est beaucoup plus facile (et moins maladroit).À moins bien sûr de votre code déjà utilisé l'identifiant
base
n'importe où. Ce qui est tout à fait possible. Keywording choses n'est pas difficile parce que le compilateur; il est difficile parce qu'il fait des choses que utilisé ces mots-clés break. Même un contexte spécifique du mot-clé signifie que vous ne pouvez pas avoir un type nommébase
.OriginalL'auteur Nicol Bolas
Contrairement à Java, C++ a l'héritage multiple. Voici un exemple où la portée de la résolution de la sorte, vous parlez devient important:
C++ n'ont pas l'héritage multiple lorsque le
::
opérateur a été introduit. Voir le Cfront E manuel, page 22 (25 dans le pdf) -::
en cours d'utilisation, mais aucun signe de l'héritage multiple dans la description des classes.OriginalL'auteur dasblinkenlight
La raison en est donnée par Stroustrup lui-même:
(Bjarne Stroustrup Une Histoire de C++: 1979-1991 page 21 - § 3.3.1)
En outre, il est vrai que
en effet
(Bjarne Stroustrup est C++ le Style et la Technique de la FAQ)
OriginalL'auteur manlio
Juste pour répondre à la final de la question sur la priorité des opérateurs:
.
avant de décider sur l'ambiguïté?Non, certainement un tel analyseur peut être écrite. Les résultats intermédiaires d'être ambigu et quand le prochain jeton vient dans vous pouvez supposer que l'utilisateur ne veut pas dire de faire une erreur de syntaxe. Donc, il n'est pas strictement nécessaire, dans ce sens, mais le '::' opérateur est utile ailleurs et analyseur C++ auteurs ont déjà suffisamment de problèmes. 🙂
La première version de C++, "Cpre" avait une parser utilisé
.
de résolution de portée (Voir le code source de Cfront, qui a été écrite pour être compilé par Cpre: softwarepreservation.org/projects/c_plus_plus/cfront/release_e/...). Après avoir compris comment le faire, j'en doute Stroustrup aurait alors renoncé à le faire de nouveau quand il réimplémentée la langue. Par conséquent, je ne pense pas que la difficulté technique de l'aide, il a fait partie de la raison.OriginalL'auteur nolandda
J'ai toujours supposé que C++ dot/:: utilisation a été un choix de style, de rendre le code plus facile à lire. Comme l'OP écrit "ils font des choses différentes, de sorte que devrait être différente."
À venir à partir de C++, il y a longtemps, C#, j'ai trouvé en utilisant uniquement des points à confusion. J'avais l'habitude de voir
A::doStuff();
B.doStuff();
, et sachant que la première est une fonction régulière, dans un espace de noms, et la deuxième est une fonction membre sur instance B.C++ est peut-être mon cinquième langue, après Basic, assembleur, Pascal et Fortran, donc je ne pense pas que c'est la première langue syndrome, et de plus je suis un programmeur C# maintenant. Mais, à mon humble avis, si vous avez utilisé les deux, C++-style double deux-points pour les espaces de noms lit mieux. J'ai envie de Java/C# a choisi de points pour les deux (avec succès) la facilité de l'avant de la courbe d'apprentissage.
OriginalL'auteur Owen Reynolds
Opérateur de résolution de portée(::) est utilisé pour définir une fonction à l'extérieur d'une classe ou lorsque l'on veut utiliser une variable globale, mais aussi a une variable locale de même nom.
OriginalL'auteur Vishal Parekh