Was bedeutet es, wenn ein Methodenaufruf mit zwei Doppelpunkten beginnt?

8

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?

    
bastibe 06.09.2010, 09:13
quelle

4 Antworten

8

Ihr Kollege hat Recht. Sie können tatsächlich eine lokale someObject definieren, die die globale someObject in diesem Bereich verbergen würde:

%Vor%

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.

    
Péter Török 06.09.2010, 09:15
quelle
4

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.

    
Michael Madsen 06.09.2010 09:18
quelle
3
  

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

verschoben werden %Vor%

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

    
Tony Delroy 06.09.2010 09:15
quelle
1

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

    
Chubsdad 06.09.2010 09:49
quelle

Tags und Links