W C++, operator ::
jest używany do dostępu do klas, funkcji i zmiennych w przestrzeni nazw lub klasie.
Gdyby specyfikacja języka używała .
zamiast ::`` w takich przypadkach, jak przy dostępie do zmiennych/metod instancji obiektu, to czy spowodowałoby to ewentualne niejasności, których nie ma w
::`?
Biorąc pod uwagę, że C+++ nie pozwala na nazwy zmiennych, które są również nazwami typów, nie mogę myśleć o przypadku, w którym mogłoby się to zdarzyć.
Wyjaśnienie: Nie pytam, dlaczego ::
został wybrany ponad .
, tylko jeśli to też mogło zadziałać?
Ze względu na próby uczynienia C++ przeważnie kompatybilnym z istniejącym kodem C (co pozwala na kolizje nazw pomiędzy nazwami obiektów i znacznikami struktury), C+++ pozwala na kolizje nazw pomiędzy nazwami klas i nazwami obiektów.
Co oznacza, że:
struct data {
static int member;
};
struct data2 {
int member;
};
void f(data2& data) {
data.member = data::member;
}
to kodeks legalny.
Przykład, w którym oba są ważne, ale odnoszą się do różnych obiektów:
#include <iostream>
Struktura A {\i1}
w i;
};
Struktura B {\i1}
w i;
A B;
};
int main() {\i1}
B x {0, 1};
std::cout << x.B.i << '\n';
std::cout << x.B::i << '\n'; std::cout << x.B::i <<;
}
Patrz na żywo na coliru.
Istnieje różnica pomiędzy a::b
i a.b
gdzie ::
implikuje, że a
jest używana jako przestrzeń nazw, co oznacza, że jest to przestrzeń nazw lub nazwa maszynowa. Pod warunkiem, że C+++ obsługuje nie-wirtualne dziedziczenie liczby mnogiej i że zmienna może mieć ten sam typ, pozbawia to szans na odwołanie się do niewłaściwego obiektu. Jest to niezbędne do metaprogramowania szablonów.
Innym przykładem może być &B::foo
vs &B.foo
w kontekście klasy B.
Rozwińmy przykład @Deduplicator:
#include <iostream>
Struktura A {\i1}
w i;
};
struktura B : publiczny A {\i1}
w i;
A A;
};
int main() {\i1}
B x {1, 2};
std::cout << x.i << '\n';
std::cout << x.B::i << '\n'; // To samo co linia powyżej.
std::cout << x.A.i << '\n'; std::cout << x.A.i << '\n'; // To samo co linia powyżej;
std::cout << x.A::i << '\n'; // To nie to samo, co linia powyżej.
}
Nie mając możliwości rozróżnienia za pomocą ::, do którego członka chcemy uzyskać dostęp, nie można uzyskać dostępu do członków zadeklarowanych w klasie macierzystej o identycznych nazwach.