Würde '::' durch 'ersetzen. 'Mehrdeutigkeiten in C ++ erstellen?


95

In C ++ wird der Operator ::verwendet, um auf Klassen, Funktionen und Variablen in einem Namespace oder einer Klasse zuzugreifen.

Wenn die Sprachspezifikation .anstelle von ::in diesen Fällen auch beim Zugriff auf Instanzvariablen / -methoden eines Objekts verwendet wird, würde dies dann zu möglichen Mehrdeutigkeiten führen, die nicht vorhanden sind ::?

Da C ++ keine Variablennamen zulässt, die auch ein Typname sind, kann ich mir keinen Fall vorstellen, in dem dies passieren könnte.

Klarstellung: Ich frage nicht, warum ::ausgewählt wurde ., nur wenn es auch hätte funktionieren können?


Kommentare sind nicht für eine ausführliche Diskussion gedacht. Dieses Gespräch wurde in den Chat verschoben .
Samuel Liew

Antworten:


124

Aufgrund der Versuche, C ++ größtenteils mit dem vorhandenen C-Code kompatibel zu machen (der Namenskollisionen zwischen Objektnamen und Struktur-Tags zulässt), ermöglicht C ++ Namenskollisionen zwischen Klassennamen und Objektnamen.

Was bedeutet, dass:

struct data {
    static int member;
};

struct data2 {
    int member;
};

void f(data2& data) {
    data.member = data::member;
}

ist legitimer Code.


11
Die Antwort auf die Frage im Titel lautet also Ja, nicht wahr?
Enrico Maria De Angelis

2
@EnricoMariaDeAngelis es ist nicht so einfach. Wäre C ++ als völlig neue Sprache wie Java oder C # entwickelt worden, könnte die Mehrdeutigkeit wahrscheinlich vermieden werden . Aber C ++ wurde als "C mit Klassen" entwickelt, und deshalb ist es nicht. "Ja, das wird es " ist eine richtige Antwort, aber auf eine andere Frage.
Kit.

Warten, ist nicht die Zuordnungslinie zeigt nur , dass die Inbetriebnahme .oder ::zwischen den gleichen zwei „Wörter“ andere Wirkung hat ( data.memberbezieht sich auf die membervon dem dataObjekt der Klasse data2, während data::memberauf das bezieht sich memberder Klasse data)?
Enrico Maria De Angelis

1
Ja, aber darauf sollten Sprachdesigner nicht stolz sein. Es ist nur ein Artefakt von Kompatibilitätsentscheidungen.
Kit.

Ok, ich verstehe, dass die heutige und bisherige Entwicklung von C ++ (auch) davon abhängt, was C zu der Zeit war, als C ++ daraus entwickelt wurde. Wenn ::man jedoch von C ++ so spricht, wie es ist, und abgesehen davon, warum es so ist, würde es eine Mehrdeutigkeit geben, wenn alle geändert würden .. In gewisser Weise haben Sie bereits mit Ja geantwortet . Ich kann einfach nicht in Ihren ersten Kommentar einbrechen. Vielleicht lässt mein Level diesen Kommentar für mich rauchig aussehen.
Enrico Maria De Angelis

37

Ein Beispiel, bei dem beide gültig sind, sich jedoch auf unterschiedliche Objekte beziehen:

#include <iostream>

struct A {
    int i;
};

struct B {
    int i;
    A B;
};

int main() {
    B x {0, 1};
    std::cout << x.B.i << '\n';
    std::cout << x.B::i << '\n';
}

Sehen Sie live auf coliru .


Und dieses Problem konnte mit unterschiedlichen Designentscheidungen nicht einfach gelöst werden!
user253751

7

Es gibt einen Unterschied zwischen a::bund a.bwo ::impliziert, dass dies aals Namespace verwendet wird, was bedeutet, dass es sich um einen Namespace oder einen Typnamen handelt. Vorausgesetzt, dass C ++ die nicht-virtuelle Pluralvererbung unterstützt und eine Variable denselben Namen wie ein Typ haben kann, verringert dies die Wahrscheinlichkeit, dass auf ein falsches Objekt verwiesen wird. Es ist für die Metaprogrammierung von Vorlagen erforderlich.

Ein anderes Beispiel wäre &B::foovs &B.fooim Kontext der Klasse B.


2

Lassen Sie @Deduplicator Beispiel erweitern:

#include <iostream>

struct A {
    int i;
};

struct B : public A {
    int i;
    A A;
};

int main() {
    B x {1, 2};
    std::cout << x.i << '\n';
    std::cout << x.B::i << '\n';  // The same as the line above.
    std::cout << x.A.i << '\n';
    std::cout << x.A::i << '\n';  // Not the same as the line above.
}

Live auf Coliru Viewer

Ohne die Möglichkeit, mit Hilfe von :: zu unterscheiden, auf welches Mitglied wir zugreifen möchten, ist es unmöglich, auf Mitglieder zuzugreifen, die in einer übergeordneten Klasse mit identischen Namen deklariert sind.


A A(Variablenname, der auch ein Typname ist) ist in C ++ jedoch nicht gültig, sodass dieses Beispiel derzeit nicht funktioniert
Jimmy RT

1
@ JimmyR.T. Es gibt das Beispiel für das Arbeitsleben in Coliru Viewer. Bestätigen Sie Ihre Aussage bitte mit einem Absatz aus dem Standard.
SM

Wenn man den verfluchten Erbdiamanten hier mit der gleichen Sache auf der anderen Seite hinzufügen würde, wäre dies ein Höhepunkt der Benennung von Schizophrenie, die in C ++
Swift - Friday Pie
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.