Ein Kollege schreibt routinemäßig so etwas:
%Vor% someObject
ist eine globale Variable.
Diese beiden Doppelpunkte scheinen mir seltsam zu sein. Der Code kompiliert und läuft ohne sie gut.
Der Kollege behauptet, dass diese Doppelpunkte someObject
explizit global machen und somit eine Verwechslung mit einem möglichen lokalen someObject
verhindern. Ich würde denken, dass Sie someObject
nicht lokal definieren könnten, wenn es bereits global definiert wäre?
Könnten Sie etwas darüber sagen, was diese Doppelpunkte bedeuten und ob sie notwendig sind?
Ihr Kollege hat Recht. Sie können tatsächlich eine lokale someObject
definieren, die die globale someObject
in diesem Bereich verbergen würde:
Scopes können rekursiv in andere Bereiche eingebettet werden, so dass Sie einen Namespace innerhalb des globalen Bereichs, eine Klasse innerhalb eines Namespaces, eine innere Klasse innerhalb der Klasse, eine Methode innerhalb einer inneren Klasse, einen Block innerhalb der Methode haben ... usw. Und Sie können Variablen / Klassen / Methoden / ... mit identischen Namen in einem dieser Bereiche haben. Das Identifizieren der Entität, auf die sich ein bestimmter Name bezieht, ist in C ++ keine triviale Aufgabe. Es ist bekannt als Name-Suche .
Kurz gesagt, wenn der Compiler einen Namen findet, sucht er den Namen beginnend mit dem innersten Bereich. I.e. Innerhalb von someMethod
wird der Name someObject
dem lokal definierten Objekt zugeordnet. ::someObject
überschreibt dieses Standardverhalten und bewirkt, dass der Compiler nur innerhalb des äußersten Bereichs (global) sucht. Daher findet es das globale Objekt anstelle des lokalen.
Sie können tatsächlich ein someObject lokal definieren, obwohl es ein globales gibt. Die beiden Variablen haben einen unterschiedlichen Gültigkeitsbereich, daher weiß der Compiler, dass es einen Unterschied zwischen den beiden gibt, und die doppelten Doppelpunkte lassen Sie auf den globalen verweisen.
Dies gilt auch für Klassen außerhalb eines Namensraums; Um beispielsweise auf eine Klasse Foo aus der Klasse Bar :: Foo zu verweisen, verwenden Sie :: Foo, um dem Compiler, über den Sie sprechen, mitzuteilen, dass er nicht in einem Namespace steht.
Hier ist ein Beispiel, das zeigt, wie es funktioniert:
%Vor%Wenn Sie diesen Code kompilieren und ausführen, wird 9 ausgegeben.
Der Kollege behauptet, dass diese Doppelpunkte mache someObject explizit global und Verhindern Sie also eine Verwechslung mit einem möglichen local someObject.
Ja - dies bedeutet, dass die Funktion nur im globalen Namespace abgeglichen werden kann und darf. Es macht deutlich, dass es sich um ein globales handelt, und würde zufälliges Vergleichen mit etwas Lokalem verhindern (beit function local, ein Objektmember, Namespacemitglied, in einem Namespace, das Sie verwenden, eine Koenig-Suchmatch usw.) / p>
Ich würde denken, dass Sie nicht sein würden kann in der Lage sein, SomeObject lokal zu definieren es wurde bereits global definiert?
Es wäre eine sehr schlechte Idee, es zu einem Fehler zu machen. Nehmen wir an, ein Team von Programmierern entscheidet, dass sie eine Variable namens "last_error" zu ihrem Namespace hinzufügen wollen: Sie sollten sich keine Sorgen machen müssen, wenn bestehende Funktionen im Namespace denselben Namen für eine lokale Variable verwenden. Wenn Sie eine Funktion von einem Namespace oder einer Klasse in einen anderen kopieren, sollten Sie keine fehleranfälligen Identifier-Substitutionen in der Implementierung vornehmen müssen.
In Bezug auf die Vorteile von ::, betrachten Sie:
%Vor% ... dann muss fn()
schnell in den Namespace Y ...
... ein zufälliges Kopieren-Einfügen in die Gedärme von Y könnte leicht übersehen, dass das Protokoll nicht mit der gleichen globalen Funktion übereinstimmt wie fn im Namespace X, aber - wie abgebildet - die Funktionalität kann sich merklich unterscheiden: -).
Sie können sich vorstellen, dass jeder Namespace, jede Klasse / Struktur und Funktionen einen Baum bilden, wobei jede Ebene eindeutig getastet sein muss (dh keine gleichnamigen Klassen im selben Namespace), aber Abhängige immer unabhängig voneinander und ihren Vorfahren sind . Die zunehmende Freiheit, sich unabhängig voneinander zu bewegen, ist wesentlich, damit viele Menschen gleichzeitig an einem großen Problem arbeiten können.
Könnten Sie etwas Licht auf was? diese Doppelpunkte bedeuten und ob sie sind notwendig?
In dieser spezifischen Verwendung ist das :: wahrscheinlich nicht unbedingt notwendig. Es fügt ein wenig Schutz hinzu, macht es aber schwerer, die Variable später in einen lokalen Bereich zu verschieben - obwohl das nicht so wichtig ist, da der Compiler Ihnen von den Orten berichten wird, die nach x immer wieder auf :: x verweisen.
Nur ein kleiner Zusatz zu allen anderen schönen Punkten, die in der Antwort enthalten sind.
Grundsätzlich :: ruft die Suche nach qualifizierten Namen im globalen Namespace auf. Es ist jedoch nicht garantiert, dass es problemfrei ist, insbesondere im Hinblick auf wahlfreie Benutzungsrichtlinien.
Der gezeigte Code veranschaulicht eine wichtige Eigenschaft der Suche nach qualifizierten Namen. Der Punkt hier ist, dass Namespaces gesucht werden, die unter Verwendung von Direktiven im globalen Namespace nominiert sind. Die Verwendung von Direktiven in Namespaces mit dem gesuchten Namen wird jedoch übersprungen.
%Vor%Wenn im Zeilencode die Zeilen mit der Direktive #if aktiviert sind, gibt es eine Mehrdeutigkeit beim Auflösen des Namens 'f'.
Tags und Links c++ language-features