Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
OpublikowałAntoni Socha Został zmieniony 9 lat temu
1
this, friend, operatory
2
this dostępny w każdej niestatycznej metodzie dostępny w każdej niestatycznej metodzie jest to wskaźnik do obiektu na rzecz którego wywołano metodę jest to wskaźnik do obiektu na rzecz którego wywołano metodę można go wykorzystać jeżeli mamy zwrócić wskaźnik bądź referencję do obiektu na rzecz którego wywoływana jest metoda można go wykorzystać jeżeli mamy zwrócić wskaźnik bądź referencję do obiektu na rzecz którego wywoływana jest metoda nie zajmuje pamięci nie zajmuje pamięci nie wymaga deklarowania nie wymaga deklarowania
3
this person & person::timeTravel(int years) { age += years; age += years; return *this; return *this;} person Boss(„John”, „Kovalsky”, 40); ( Boss.timeTravel(+20) ).timeTravel(-30)
4
friend po polsku zaprzyjaźnianie po polsku zaprzyjaźnianie jest to deklaracja znosząca ograniczenia dostępu do składowych klasy przez ściśle określony kod jest to deklaracja znosząca ograniczenia dostępu do składowych klasy przez ściśle określony kod
5
friend class A { friend C::theMethodNoArg(); friend C::theMethodNoArg(); // dotyczy konkretnej metody, tu bezargumentowej // dotyczy konkretnej metody, tu bezargumentowej friend class B; friend class B; // dotyczy całej deklaracji klasy B // dotyczy całej deklaracji klasy B // również deklaracje wewnątrz B mają dostęp // również deklaracje wewnątrz B mają dostęp // do pól prywatnych A // do pól prywatnych A friend fun(); friend fun(); // dotyczy konkretnej funkcji, tu bezargumentowej // dotyczy konkretnej funkcji, tu bezargumentowej}
6
friend zaprzyjaźnianie nie podlega dziedziczeniu zaprzyjaźnianie nie podlega dziedziczeniu zaprzyjaźnianie nie jest przechodnie zaprzyjaźnianie nie jest przechodnie deklarowane w dowolnej sekcji (nawet prywatnej) klasy deklarowane w dowolnej sekcji (nawet prywatnej) klasy
7
friend class M { friend void f() … { … } }; jest równoważne class M { friend void f(); }; void f() { … }
8
Operatory Co to jest operator? Co to jest operator? a = b.val >> 4 + c * d[ e++ ]
9
Operatory operator definiuje operacje wykonywane na swoich argumentach i typ wyniku takiej operacji – analogicznie do funkcji. operator definiuje operacje wykonywane na swoich argumentach i typ wyniku takiej operacji – analogicznie do funkcji. w C++ można definiować znaczenie operatorów w przypadku wykorzystania ich do obiektów (przynajmniej jeden argument obiektowy). w C++ można definiować znaczenie operatorów w przypadku wykorzystania ich do obiektów (przynajmniej jeden argument obiektowy).
10
Operatory Można przeciążać większość operatorów Można przeciążać większość operatorów Przeciążanie może poprawić wydajność Przeciążanie może poprawić wydajność Nie ma obowiązku a zwykle nie ma i potrzeby definiowania wielu operatorów, jeżeli operator byłby sporadycznie używany to zaleca się deklarowanie go jako metody bądź zwykłej funkcji. Nie ma obowiązku a zwykle nie ma i potrzeby definiowania wielu operatorów, jeżeli operator byłby sporadycznie używany to zaleca się deklarowanie go jako metody bądź zwykłej funkcji.
11
Operatory które można przeciążać () [] -> + - ++ -- ! ~ * & new delete (typ) // jednoargumentowe ->* * / % + - > > >= >= == != &^|&&|| = += -= *= /= %= &= ^= |= >= // op. przypisania
12
Operatory nie można przeciążać operatorów: nie można przeciążać operatorów:..* ::?:sizeof operatory, które mogą być jedynie metodami klasy: operatory, które mogą być jedynie metodami klasy: ()[]->newdelete(typ)= operatory domniemane, jeżeli nie zdefiniowane: operatory domniemane, jeżeli nie zdefiniowane: =&
13
Łączność operatory przypisania i jednoargumentowe są prawostronnie łączne operatory przypisania i jednoargumentowe są prawostronnie łączne a=b=c oznacza a=(b=c) pozostałe lewostronnie pozostałe lewostronnie a+b+c oznacza (a+b)+c
14
Kolejność wartościowania kolejność wartościowania argumentów niezdefiniowana, za wyjątkiem: kolejność wartościowania argumentów niezdefiniowana, za wyjątkiem:,||&&,||&& „, ”, „ || ”, „ && ” najpierw wartościowany lewy argument, potem prawy „, ”, „ || ”, „ && ” najpierw wartościowany lewy argument, potem prawy dla operacji logicznych stosowane jest skrócone wartościowanie. dla operacji logicznych stosowane jest skrócone wartościowanie.
15
Operatory a metody inna składnia deklaracji, definicji i wywołania inna składnia deklaracji, definicji i wywołania operatory nie mogą mieć argumentów domyślnych (wyjątek: operator wywołania funkcji) operatory nie mogą mieć argumentów domyślnych (wyjątek: operator wywołania funkcji) określona jest liczba argumentów (wyjątek: operator wywołania funkcji) określona jest liczba argumentów (wyjątek: operator wywołania funkcji) przyjęte jest zwyczajowe znaczenie operatorów przyjęte jest zwyczajowe znaczenie operatorów
16
Operatory Chcesz += to zdefiniuj go, Chcesz += to zdefiniuj go, nie wystarczy zdefiniować + i = Chcesz ++ to zdefiniuj go, Chcesz ++ to zdefiniuj go, kompilatorowi nie wtstarczy + i = Zachowaj wierność zwyczajowemu znaczeniu operatorów Zachowaj wierność zwyczajowemu znaczeniu operatorów niech jednoarg. & zwraca adres niech jednoarg. & zwraca adres Zachowaj konsekwencję Zachowaj konsekwencję ++i; i++; i+=1; i=i+1; // powinny dawać taki sam efekt. ++i; i++; i+=1; i=i+1; // powinny dawać taki sam efekt.
17
Operatory jako metody pierwszy argument będzie obiektem klasy pierwszy argument będzie obiektem klasy metoda ma mniej argumentów niż operator metoda ma mniej argumentów niż operator deklarowanie deklarowanie int point::operator<=(point); wywoływanie wywoływanie point point1, point2; int i= point1 <= point2; int j= point1.operator<=(point2);
18
Operatory jako funkcje przynajmniej jeden z argumentów musi być obiektem przynajmniej jeden z argumentów musi być obiektem wszystkie argumenty są parametrami funkcji operatorowej wszystkie argumenty są parametrami funkcji operatorowej nie ma this nie ma this deklarowanie deklarowanie int operator<=(point, point); wywoływanie wywoływanie point point1, point2; int i = point1 <= point2; int j= operator<=(point1, point2);
19
Konwencja dla operatorów ++ i -- operator++() i operator--() są przedrostkowe operator++() i operator--() są przedrostkowe ++i--i operatory przyrostkowe deklarujemy i definiujemy z dokładnie jednym nienazwanym parametrem int: operatory przyrostkowe deklarujemy i definiujemy z dokładnie jednym nienazwanym parametrem int: operator++(int); operator--(int); i++i--
20
Konwencja dla operatorów ++ i -- class X { public: X& operator++(); // prefix ++a X operator++(int); // postfix a++ }; class Y { public: }; Y& operator++(Y&); // prefix ++b Y operator++(Y&, int); // postfix b++
21
Konwencja dla operatorów ++ i -- void f(X a, Y b) { ++a; // a.operator++(); a++; // a.operator++(0); ++b; // operator++(b); b++; // operator++(b, 0); a.operator++(); // odpowiada ++a; a.operator++(0); // odpowiada a++; operator++(b); // odpowiada ++b; operator++(b, 0); // odpowiada b++; }
22
Operatory class X // składowe z niejawnym this { X* operator&();// przedrostkowy, jednoargumentowy & X operator&(X);// dwuargumentowy X operator++(int);// przyrostkowy //X operator&(X, X);// blad trzyargumentoowy //X operator/();// blad jednoarg. }; // funkcje globalne, bez this, często zaprzyjazniane X operator-(X);// przedrostkowy X operator-(X, X);// dwuargumentowy X operator--(X&, int);// przyrostkowy dekrementacja // X operator-(X, X, X);// blad trzyargumentoowy // X operator/();// blad operator bezargumentowy! ;)
23
Operator przypisania Musi być zdefiniowany jako metoda (niestatyczna) a nie jako funkcja Musi być zdefiniowany jako metoda (niestatyczna) a nie jako funkcja T& T::operator=(const T &) Nie ma listy inicjalizacyjnej bo to nie jest konstruktor !!! Nie ma listy inicjalizacyjnej bo to nie jest konstruktor !!!
24
Operator przypisania person& person::operator=(const person &o) { if (this == &o) // Tom = Tom; if (this == &o) // Tom = Tom; return *this; return *this; delete [] name; delete [] name; name=new char[strlen(o.name) + 1]; name=new char[strlen(o.name) + 1]; strcpy(name, o.name); strcpy(name, o.name); delete [] lastName; delete [] lastName; lastName=new char[strlen(o.lastName) + 1]; lastName=new char[strlen(o.lastName) + 1]; strcpy(lastName, o.lastName); strcpy(lastName, o.lastName); age=o.age; age=o.age; return *this;// zwraca obiekt, będzie przekazany przez referencje return *this;// zwraca obiekt, będzie przekazany przez referencje}
25
Operator przypisania dlaczego operator przypisania zwraca referencję? dlaczego operator przypisania zwraca referencję? chcemy napisać o1=o2=o3; chcemy napisać o1=o2=o3; person& operator=(const person&); 1. przypisania do: o2 z: o3 2. operator przypisania do: o1 z: (o2=o3) person operator=(const person&); 1. przypisania do: o2 z: o3 2. konstruktor kopiujący (powstaje tymczasowy obiekt t1) 3. operator przypisania do: o1 z: t1 4. konstruktor kopiujący (powstaje tymczasowy obiekt t2) 5. destruktor t2 6. destruktor t1
26
Operator przypisania dlaczego operator przypisania zwraca referencję? dlaczego operator przypisania zwraca referencję? chcemy napisac o1=o2=o3; chcemy napisac o1=o2=o3; void operator=(const person&); void operator=(const person&); można o2=o3; można o2=o3; nie da się o1=o2=o3; nie da się o1=o2=o3;
27
Operator przypisania generowany automatycznie jeżeli się nie zdefiniuje operatora przypisania to kompilator dostarczy własny operator przypisania, który skopiuje obiekt pole po polu. jeżeli się nie zdefiniuje operatora przypisania to kompilator dostarczy własny operator przypisania, który skopiuje obiekt pole po polu. nie będzie działał dla pól stałych nie będzie działał dla pól stałych nie będzie działał dla dla referencji nie będzie działał dla dla referencji dla wskaźników skopiuje wartość dla wskaźników skopiuje wartość
28
Operatory strumieniowe Wejście Wejście friend istream & operator >>(istream &, T &); Wyjście Wyjście friend ostream &operator <<(ostream &, const T &);
29
Operatory strumieniowe class point { int x, y; int x, y;public:… friend istream &operator >>(istream & s, point & p); friend istream &operator >>(istream & s, point & p); friend ostream &operator <<(ostream & s, const point &); friend ostream &operator <<(ostream & s, const point &);} point p, p2; cin>>p;cin>>p>>p2;cout<<p2<<p;
30
Operatory strumieniowe istream & operator >>(istream & s, point & p) { s >> p.x >> p.y; s >> p.x >> p.y; return s; return s;} ostream &operator <<(ostream & s, const point & p) { s << p.x << p.y; s << p.x << p.y; return s; return s;}
31
Operator wyłuskania T* operator->(); T t; T t; t->m jest interpretowane jako: t->m jest interpretowane jako: ( t.operator-> )->m można używać zmiennej jak wskaźnika można używać zmiennej jak wskaźnika jeżeli operator-> nie zwraca wskaźnika to jeżeli operator-> nie zwraca wskaźnika to można użyć go: a=t.operator->(); można użyć go: a=t.operator->(); nie można: a=t->; bo to błąd składniowy nie można: a=t->; bo to błąd składniowy
32
Operator wywołania funkcji wynik T::operator()(args); Dowolna liczba argumentów, można przeciążać Dowolna liczba argumentów, można przeciążać Wyjątek: tylko ten operator może mieć domyślne argumenty Wyjątek: tylko ten operator może mieć domyślne argumenty potem można obiekt używać tak, jak funkcję potem można obiekt używać tak, jak funkcję T ob; ob(); stosuje się gdy stosuje się gdy nie istnieje odpowiedni operator, a by się przydał nie istnieje odpowiedni operator, a by się przydał jest jakś metoda dominująca dla klasy (będzie bez nazwy ale łatwiejsza do wywołania – np. klasa counter i metoda inkrementacja) jest jakś metoda dominująca dla klasy (będzie bez nazwy ale łatwiejsza do wywołania – np. klasa counter i metoda inkrementacja)
33
operator indeksowania wynik T::operator[](index); typy wyniku i indeksu dowolne ale zdrowy rozsądek nakazuje indeks całkowity typy wyniku i indeksu dowolne ale zdrowy rozsądek nakazuje indeks całkowity można tworzyć inteligentne agregaty, można tworzyć inteligentne agregaty,
34
Operator konwersji operator konwersji tworzy obiekt określonego typu lub klasy z obiektu na rzecz którego jest wywoływany operator konwersji tworzy obiekt określonego typu lub klasy z obiektu na rzecz którego jest wywoływany T::operator X(); operator konwersji klasy T do typu X: operator konwersji klasy T do typu X: nie określa się jawnie typu wartości zwracanej, nie określa się jawnie typu wartości zwracanej, jest bezargumentowy jest bezargumentowy musi być metodą (nie funkcją) musi być metodą (nie funkcją)
35
Operator konwersji np.: np.: person::operator int(); konwersja może następować niejawnie: konwersja może następować niejawnie: person o; int i=o+5; W wyrażeniach W wyrażeniach dla danego obiektu konwersja jest stosowana tylko jeżeli jest konieczna, dla danego obiektu konwersja jest stosowana tylko jeżeli jest konieczna, może być tylko jedna konwersja danego składnika definiowana przez użytkownika może być tylko jedna konwersja danego składnika definiowana przez użytkownika nie może być niejednoznaczności nie może być niejednoznaczności
36
Operator konwersji np. dla klas: A, B i C, zdefiniowano operatory konwersji B::operator A() i C::operator B(); np. dla klas: A, B i C, zdefiniowano operatory konwersji B::operator A() i C::operator B(); int f(A a); A a; B b; C c; f(a); // ok.. f(b); // f(A(b)) // f(c); // nie ma operatora C::operator A() // nie zrobi się niejawnie f(A(B(c))) // (2 konwersje skladnika)
37
Operator konwersji aby przekształcić obiekt jednego typu w obiekt innego typu można jawnie użyć konstruktora, ale: aby przekształcić obiekt jednego typu w obiekt innego typu można jawnie użyć konstruktora, ale: nie da się przeprowadzić przekształcenia do typu podstawowego (np. int, bo to nie klasa), nie da się przeprowadzić przekształcenia do typu podstawowego (np. int, bo to nie klasa), nie da się przekształcić do starej klasy bez modyfikowania jej definicji. nie da się przekształcić do starej klasy bez modyfikowania jej definicji.
38
Przykład class counter { int cnt; int cnt; public: public: counter(int i=0):cnt(i){}; counter(int i=0):cnt(i){}; int operator()(int =1); // increment by arg. or by 1 int operator()(int =1); // increment by arg. or by 1 operator int(); // convert to int operator int(); // convert to int operator double(); // convert to double operator double(); // convert to double counter &operator+=(int); counter &operator+=(int); friend counter operator+(int, counter); // int+counter, friend friend counter operator+(int, counter); // int+counter, friend counter operator+(int); // counter+int counter operator+(int); // counter+int int operator++();// ++counter int operator++();// ++counter int operator++(int);// counter++ int operator++(int);// counter++};
39
Przykład inline int counter::operator ()(int i) { return cnt+=i; return cnt+=i;} inline counter::operator int() { return cnt; return cnt;} inline counter::operator double() { return double(cnt); return double(cnt);}
40
Przykład counter & counter::operator +=(int i) { cnt+=i; // operator()(i); (*this)(i) cnt+=i; // operator()(i); (*this)(i) return *this; return *this;} counter operator+(int i, counter l) { l+=i; // zaprzyjaźnianie nie było konieczne l+=i; // zaprzyjaźnianie nie było konieczne return l; return l;}
41
Przykład counter counter::operator +(int i) { counter l=*this; counter l=*this; l+=i; l+=i; return l; return l;} int counter::operator ++() { cnt+=1; cnt+=1; return cnt; return cnt;} int counter::operator ++(int) { int ret=cnt; int ret=cnt; cnt+=1; cnt+=1; return ret; return ret;}
42
Przykład class complex { double re, im; double re, im;public: complex(double re, double im):re(re), im(im) {}; complex(double re, double im):re(re), im(im) {}; complex & operator = (const complex &c); complex & operator = (const complex &c); complex & operator += (const complex &c); complex & operator += (const complex &c); complex operator + (const complex &); complex operator + (const complex &); friend complex & operator -= (complex &, const complex &); friend complex & operator -= (complex &, const complex &); friend complex operator - (const complex &, const complex &); friend complex operator - (const complex &, const complex &); friend istream & operator >>(istream &, complex &); friend istream & operator >>(istream &, complex &); friend ostream & operator <<(ostream &, const complex &); friend ostream & operator <<(ostream &, const complex &);};
43
Przykład complex & complex::operator = (const complex &c) { re=c.re; re=c.re; im=c.im; im=c.im; return *this; return *this; }
44
Przykład complex & complex::operator += (const complex &c) { re+=c.re; re+=c.re; im+=c.im; im+=c.im; return *this; return *this; } inline complex complex::operator + (const complex & c) { return complex(re+c.re, im+c.im); // complex(double, double) return complex(re+c.re, im+c.im); // complex(double, double)}
45
Przykład inline complex & operator-=(complex & c1, const complex & c2) //friend { c1.re-=c2.re; c1.re-=c2.re; c1.im-=c2.im; c1.im-=c2.im; return c1; return c1;} complex operator-(const complex & c1, const complex & c2) //friend { complex c=c1; complex c=c1; c-=c2; c-=c2; return c; return c;}
46
Przykład istream & operator >>(istream & s, complex & c) { s >> c.re >> c.im; s >> c.re >> c.im; return s; return s;} ostream &operator <<(ostream & s, const complex & c) { s << c.re << c.im; s << c.re << c.im; return s; return s;}
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.