Jaki jest cel następujących ezoterycznych operatorów C++?Ezoteryczni operatorzy C++
wskaźnik z członem
::*
Bind wskaźnika z członem przez wskaźnik
->*
Bind wskaźnik do członka poprzez odniesienie
.*
Jaki jest cel następujących ezoterycznych operatorów C++?Ezoteryczni operatorzy C++
wskaźnik z członem
::*
Bind wskaźnika z członem przez wskaźnik
->*
Bind wskaźnik do członka poprzez odniesienie
.*
Wskaźnik do elementu pozwala mieć wskaźnik, który jest względem konkretnej klasy.
Załóżmy, że masz klasę kontaktów z wieloma numerami telefonów.
class contact
{
phonenumber office;
phonenumber home;
phonenumber cell;
};
Chodzi o to, czy masz algorytmu, który musi użyć numeru telefonu, ale decyzję, której numer telefonu powinny być wykonane poza algorytmem, wskaźniki do członka rozwiązania problemu:
void robocall(phonenumber contact::*number, ...);
teraz wywołujący robocall może zdecydować, jaki rodzaj PHONENUMBER używać:
robocall(&contact::home, ...); // call home numbers
robocall(&contact::office, ...); // call office number
.*
i ->*
wchodzić w grę raz masz wskaźnik. Więc wewnątrz robocall, zrobiłbyś:
contact c = ...;
c.*number; // gets the appropriate phone number of the object
czyli
contact *pc = ...;
pc->*number;
To naprawdę fajne. –
W InformIT znajduje się czytelny przewodnik [Wskaźniki dla członków] (http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=142). –
Oto ich ładny przykład: http://msdn.microsoft.com/en-us/library/k8336763.aspx –
Zapoznaj się z C++ FAQ Lite's section on pointers to member functions. Wyszukaj określonych "operatorów", o których mówisz (w większości przeglądarek Ctrl-F otwiera okno dialogowe Znajdź/Wyszukaj, które umożliwia wyszukiwanie tekstu na stronie internetowej) i powinno pomóc ci lepiej zrozumieć rzeczy.
Przesadnie uproszczona odpowiedź - operatory te umożliwiają wywoływanie funkcji członków jako "zwykłych" funkcji (przynajmniej wygląda to tak samo z perspektywy użytkownika końcowego). Przykład z rzeczywistego świata - są one często używane w różnych implementacjach wywołań zwrotnych.
Nie ma takiego operatora, jak ::*
i nigdy nie było. Nie wiem, skąd to masz.
chodzi o ->*
i .*
- są operatorzy Dereferencjuj wskaźników z wskaźnik do członka typu.
struct S {
int i;
};
int main() {
int S::*pi = &S::i; // pointer of pointer-to-member type
S s;
S* ps = &s;
s.*pi = 0; // operator `.*` used
assert(s.i == 0);
ps->*pi = 1; // operator `->*` used
assert(s.i == 1);
}
Co do tego, co podpowiadają członkowie, to ... co powie twoja ulubiona książka w C++ na ten temat?
Mam :: * z wikipedii wymienionych jako odniesienie do mojego pytania. –
:: * kompiluje się dobrze w g ++. –
@Neil G: Co dokładnie "kompiluje się dobrze w g ++"? – AnT
Umożliwia to wyświetlanie wskaźników do funkcji składowych (i zmiennych składowych), które są powiązane z konkretnym wystąpieniem klasy.
Wskaźniki do funkcji elementów mogą być przydatne do takich rzeczy jak lekkie implementacje wzorca stanu.Generalnie, za każdym razem, gdy chcesz zmienić zachowanie obiektu w czasie bez uciekania się do wyłączania całego obiektu, możesz rozważyć użycie wskaźników do funkcji członków.
Wskaźniki do zmiennych składowych mogą być użyte, jeśli chcesz np. Zaimplementować ogólny algorytm przeszukiwania tablicy struktur dla pozycji, która ma określoną wartość dla danego pola.
Dotyczą one funkcji wskaźników do członków i wskaźników do członków.
struct Foo {
int a() { return 1; }
int b() { return 2; }
int c;
};
int main() {
Foo f;
f.c = 3;
typedef int (Foo::*member_fn)(); // pointer-to-member-function
typedef int (Foo::*data_member); // pointer-to-member
member_fn mf = &Foo::a;
(f.*mf)(); // calls the member function pointed to by mf. returns 1
mf = &Foo::b;
(f.*mf)(); // This time, returns 2, since mf points to b
Foo *fp = &f;
(fp->*mf)(); // same thing, via pointer to f instead of object/reference f.
data_member dm = &Foo::c;
f.*dm; // is 3
f.*dm = 5;
f.c; // is now 5.
Foo f2; // another instance
f2.c = 12;
f2.*dm; // is 12. Same pointer-to-member, different object.
}
Chociaż może wyglądać jak jeden, ::*
nie jest operatorem. Jest to operator ::
i modyfikator typu *
obok siebie. Aby to udowodnić bez odwoływania się do standardu, spróbuj dodać spacje: :: *
kompilacje, . *
nie, ani nie ma -> *
.
Co do tego, do czego są one faktycznie przydatne - ta sama zasada co wskaźniki funkcji. Nie używałbyś ich tak jak powyżej, w sytuacji, w której możesz po prostu wywołać funkcję po nazwie, ale możesz przekazać je jako parametry lub zwrócić je z funkcji, zapisać lub wybrać jedną z kilku na podstawie skomplikowanej logiki.
Jeśli to pomoże, wierzę składnia jest tak dobrana, że chociaż .*
jest niepodzielny pojedynczy operator, można sobie wyobrazić, że *dm
„oznacza” c
, element wskazywany przez DM. Więc jeśli dm
wskazuje na c
, to f.*dm
jest taki sam jak f.c
.
Niezależnie od wikipedia, ':: *' nie jest operatorem. –