@MarkusB/pytanie A
:: dokladnie tak sie nazywa, ale uzywa sie go w wielu roznych miejscach.
jedno z nich to "chodzenie" po namespaceach,
inne, to "chodzenie" po skladnikach klasy
namespace A
{
namespace B
{
int zmienna;
class C
{
int pole;
class D { int pole2; };
};
}
}
pelna nazwa zmiennej globalnej: A::zmienna
pelna nazwa pola klasy: A::pole
pelna nazwa pola innerklasy: A::pole
jezeli teraz chcesz w dowolnym miejscu kodu powiedziec, niech zmienna globalna wynosi 5, zapiszesz to:
A::B::zmienna = 5;
B::zmienna = 5;
zmienna = 5;
w zaleznosci w ktorym miejscu aktualnie "się" znajdujesz względem struktury namespaceow.
podobnie, jezeli "jestes" poza klasa, jakos musisz wskazac że chodzi Ci po 'pole' z klasy C a nie D, zapisy:
&C::pole
&D::pole
powinny więc być dla Ciebie w miare oczywiste
teraz, "luźnolatający" wskaznik na int, to jest po prostu int*
wskaznik na cos-w-klasie nie jest "luźnolatający", poniewaz aby go uzyc musisz podac instancje klasy. obiekt:
int a = 5;
int b = 5;
int* wskaznik = &a;
.....
int cede = *wskanzik; //odczyta zawartosc 'a', nie 'b'
class Klasa{int POLE, POLEINNE;};
Klasa a = .....;
Klasa b = .....;
???? wskaznik = &Klasa::POLEINNE; // ustawiamy wskaznik na pole 'POLEINNE' klasy.
.....
//cede = *wskaznik; -- nie mozna! z czego mial by ten wskaznik odczytac? z obiektu A czy obiektu B?
cede = a .* wskaznik; //bierzemy obiekt, a potem na nim wywolujemy wskanzik-na-pole. odczyta zawartosc z 'a', nie 'b'
jak sie zastanowic, roznica uzycia wskaznika-na-zawartosc oraz zwyklego wskaznika robi sie w miare sensowna. specjalnie w kodzie powyzej napisalem ????? zamiast typu wskaznika. roznica w nich oznacza, ze ????? to nie jest int*. jak wiec zapisac ze wskaznik ma byc na-int, ale ze dodatkowo ma byc na-cos-w-klasie-Klasa?
odpowiedz brzmi: do definicji wskaznika trzeba dolaczyc operator zakresu, ::
Co WCzym::* zmienna; kontra Co * zmienna;
z namespaceow pamietasz pewnie, ze "topowy" namespace to puste ::, tutaj tez to NIE funkcjonuje, ale mozesz tak na to patrzec:
Co WCzym::* zmienna; kontra Co ::* zmienna;
prawa wersja mowi, ze wskazywane "co" jest na samej gorze, nie jest opakowane
lewa wersja mowi, ze "Co" ma byc opakowane przez WCzym
specjalny zapis " WCzym::* " to wskaznik-w-opakowanie.
z namespaceami:
int (A::* zmienna) = &A::pole ---- adres pola w klasie D w klasie C w namespace A::B
niestety, skladnia C++ jest jesli chodzi o wskazniki totalnie kontra-intuicyjna. tak samo jak zapis wskaznikow na zlozone tablice czy funkcje jest wrogi, tak tutaj jest tylko troszke lzej.. moze i pieknie by bylo, gdybysmy kiedys mogli napisac: A::int* zmienna = &A::pole;
... ale wtedy skad kompilator by wiedzial, ze chodzi o TEN int, a nie o nasza klase ktora siedzi w A:: i nazywa sie 'int'? nie daloby sie. kolejna proponowalna 'lepsza' skladnia to np. A::(std::int)* zmienna = &A::pole; ale szczerze, ja juz przywyklem do obecnej i juz mnie malo rzeczy razi (jak sobie rozważę alternatywy:) )