1 / 19

Przeciążanie operatorów

Przeciążanie operatorów. Na czym to polega ?. Krótko mówiąc, aby zmusić znaczki typu: +,- itd. Aby robiły to co im każemy. Kluczem do zrozumienia pisania operatorów jest fakt abyśmy uświadomili sobie, że sami możemy napisać funkcję "operatora dodawania", która będzie

magnar
Download Presentation

Przeciążanie operatorów

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Przeciążanie operatorów Na czym to polega ? Krótko mówiąc, aby zmusić znaczki typu: +,- itd. Aby robiły to co im każemy. Kluczem do zrozumienia pisania operatorów jest fakt abyśmy uświadomili sobie, że sami możemy napisać funkcję "operatora dodawania", która będzie wywoływana wtedy, gdy obok znaczka + pojawią się argumenty wybranego przez nas typu. W tym momencie zostanie przeładowany operator +.

  2. Przeciążanie operatorów Czym specjalnym wyróżnia sie taka funkcja? NICZYM, poza nazwą, która musi przyjąć postać operatorX, gdzie X oznacza wybrany przez nas operator (np.: +,-,/,*). Poza tym jest to najzwyklejsza w świecie funkcja, która o dziwo wcale nie musi dodawać, odejmować itd. , może po prostu zagwizdać naszym głośniczkiem w komputerze. Kluczowym elementem jest to, że kiedy kolo obiektu naszej klasy pojawi się znak + to funkcja zostanie uruchomiona automatycznie! obiekt1 + obiekt2 Można również wywołać ją jak zwykłą funkcję operator+(obiekt1,obiekt2)

  3. Przykład: Rozważmy klasę która opisuje współrzędne punktów: class wsp{ public: float osX; float osY; wsp operator+(wsp a,wsp b){ wsp suma; suma.osX = a.osX + b.osX; suma.osY = a.osX + b.osY; return suma; } }; Przeciążanie operatorów Ten przykład obrazuje w jaki sposób możemy przeciążyć operator ‘’+’’ lub jakikolwiek inny.

  4. Przeciążanie operatorów Wiemy już zatem, że można przeładować operator +. Nasuwa się pytanie kiedy to robić? Oczywiście w sytuacji, gdy wobec obiektu danej klasy bardziej naturalne wydaj się używać znaku + niż wywołanie funkcji. Jest to moment, w którym powinniśmy rozważyć możliwość przeładowania. Często się tak dzieje wobec klas powiązanych z matematyka .Lecz niekoniecznie, można przecież napisać: ekran + okno w celu ujrzenia na ekranie okienka.

  5. Przeciążanie operatorów Operator przypisania „=” //Manipulowanie łańcuchami w c: char napis[10]; napis = „Tekst”; //błąd strcpy(napis, „Tekst”); //poprawnie

  6. Przeciążanie operatorów //Wersja w C++: string napis; napis = „Tekst”; //poprawnie, gdyż w klasie string przeciążony //został operator przypisania „=” Przeciążanie operatorów jest techniką mającą głównie na celu zwiększenie czytelności programu i ułatwienie manipulowania obiektami.

  7. Przykład przeciążenia operatora przypisania „=” class Napis{ private: char bufor[100]; public: Napis &operator=(const char* str); void set(const char* str) {strcpy(bufor, str);} const char *get() {return bufor;}};Napis &Napis::operator=(const char* str){ set(str); return *this;}int main(int argc, char *argv[]){ Napis napis; napis = "PO to nasz ulubiony przedmiot:)"; cout << napis.get(); return 0;}

  8. Przykład przeciążenia operatora indeksowania „[ ]” class Napis{ private: char bufor[100]; public: Napis &operator=(const char* str); char operator[](int i) {return bufor[i];} void set(const char* str) {strcpy(bufor, str);} const char *get() {return bufor;}};Napis &Napis::operator=(const char* str){ set(str); return *this;}int main(int argc, char *argv[]){ Napis napis; napis = "PO to nasz ulubiony przedmiot:)"; for (int i = 0; i < 10; ++i) cout << napis[i]; return 0;}

  9. Przeciążanie operatorów Uwagi: 1.Przeładowywać można tylko powyżej podane operatory, nie można wymyślać swoich. 2.Przeładowanie może nadać operatorowi dowolne znaczenie, nie ma też ograniczeń co do wartości zwracanej przez operator(wyjatki to: new i delete). 3.Nie można jednak zmienić priorytetu wykonywania tych operatorów. na przykład: Wyrażenie a+b*c zawsze będzie wykonywane jako a+(b*c) a nie jako (a+b)*c

  10. Przeciążanie operatorów 4.Nie można zmienić argumentowości operatorów, czyli tego czy operator jest jedno czy dwu argumentowy. Przykładowo: operator / (mnożenie) zawsze będzie dwu argumentowy. przykład: element1 / element2 //dobrze! element1 / element2/ //źle Tak samo z operatorem ! (negacji) , jest jedno argumentowy.Nie możemy wiec napisać element1 ! element2 // źle !element1 // dobrze 5. A oto lista operatorów które można przeciążać: + - * / % ^ & | - ! = < > += -= /= %= ^= &= |= << >> >>= <<= == != <= >= && || ++ -- , ->* -> () []

  11. Przyjaźń. Funkcje i Klasy zaprzyjaźnione. Relacje przyjaźni są to stosunkowo niedawno dodane właściwości C++. Funkcje zaprzyjaźnione nie są jedynymi rodzajami form zaprzyjaźnionych jakie może posiadać klasa. Sama klasa również może być zaprzyjaźniona. W takim przypadku każda metoda klasy zaprzyjaźnionej ma dostęp do prywatnych chronionych składowych klasy oryginalnej.

  12. To klasa definiuje jakie funkcje, metody lub inne klasy są w stosunku do niej formami zaprzyjaźnionymi. • Relacje „przyjaźnienia się” nie mogą być narzucane z zewnątrz do prywatnych składowych klasy, w rzeczywistości nie naruszają one żadnych idei programowania obiektowego. • Głównym celem, „przyjaźnienia się” jest uelastycznienie interfejsu publicznego. • Po co chcieć zaprzyjaźnić jakąś klasę z inną ? Popatrzmy na przykład.

  13. Class Tv { public: friend class Pilot ; // Klasa Pilot ma dostęp do części prywatnej klasy TV void onOff (void){ // instrukcje } void metoda(void ){ //instrukcje } private: int stan ; int glosnosc; int wejscie; int ustawKanal(int kanal) { } }

  14. Class Pilot { private : int tryb ; public : bool glosniej (Tv & t) { return t.glosniej(); } bool ciszej (Tv & t) { return t.ciszej();} void onOff (Tv & t) { t.onOff(); } void ustaw() {ustawKanal(int kanal);} }; Uwaga : Każda z metod klasy Pilot pobiera jako argument referencje do obiektu Tv - jest to odzwierciedlenie faktu skojarzenia pilota z określonym telewizorem.

  15. Funkcje zaprzyjaźnione Niezależne funkcje zaprzyjaźnione mają dostęp do składowych prywatnych i chronionych klasy. Sama funkcja nie nabywa własności składowej klasy. class Punkt { static int ile_punktow; float x, y; public: friend void wyswietl(punkt&); // deklaracje friend friend void wyswietl(punkt*); friend void wyswietl(punkt, char); friend void wyswietl(); };

  16. void wyswietl(punkt& p) { cout<<”Przekazanie przez referencje punktu o “; cout <<”wspolrzednych: “ << p.y << “ “<< p.y << “\n”; getch(); } void wyswietl(punkt *p) { ciało funkcji bez hermetyzacji obiektu p } void wyswietl(punkt p, char) { ciało funkcji bez hermetyzacji obiektu p } void wyswietl() { cout <<"Liczba punktow: " << punkt::ile_punktow << "\n"; }

  17. Funkcje zaprzyjaźnione z wieloma klasami Niezależna funkcja zaprzyjaźniona z kilkoma klasami ma dostęp do wszystkich składowych prywatnych i chronionych tych klas. Sama funkcja nie nabywa jednak własności składowej tych klas. Deklaracja zaprzyjaźnienia powinna wystąpić w każdej z tych klas, natomiast definicja tylko raz . class Kolo; // niezbędna deklaracja klasy kolo ze względu na deklaracjęfriend classPunkt { staticint ile_punktow; float x, y; public: friendvoid wyswietl(kolo&); // deklaracja friend }; class Kolo { staticint ile_kol; float promien; punkt srodek; public: friendvoid wyswietl(kolo&);}; // deklaracja friend

  18. Dzięki zaprzyjaźnieniu do wyświetlenia utworzono jedną funkcje wyświetl. W ciele funkcji są dostępne wszystkie składowe klas kolo i punkt • Język C++ dopuszcza również możliwość wskazania poszczególnych składowych klasy, które mają być zaprzyjaźnione lecz, jest to trochę kłopotliwe. • W takiej sytuacji powinniśmy pamiętać o zachowaniu odpowiedniej kolejności w jakiej pojawiają się różne deklaracje i definicje.

  19. Przykład : Chcąc zaprzyjaźnić metodę Pilot :: ustaw kanał () z klasą Tv należy zadeklarować ją z przedrostkiem friend i umieścić w sekcji deklaracyjnej klasy Tv class Tv { friend Pilot :: ustaw kanał (Tv &t ) } • Jednakże aby kompilator mógł przetworzyć taką instrukcję, wcześniej musi do definicji klasy Pilot. W przeciwnym wypadku nie będzie wiedział, że Pilot jest klasą a ustawkanal() metodą tej klasy. Jednak metody klasy Pilot odwołują się do klasy Tv. • W tym celu przed definicją klasy Pilot trzeba umieścić „zapowiedź” klasy Tv class Tv ; // deklaracja zapowiadająca class Pilot {….}; class Tv {…..};

More Related