przeciążanie operatorów

19
Przeciążanie operatorów 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 +. Na czym to polega ?

Upload: magnar

Post on 05-Jan-2016

25 views

Category:

Documents


0 download

DESCRIPTION

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 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Przeciążanie operatorów

Przeciążanie operatorów

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ędziewywoływana wtedy, gdy obok znaczka + pojawią się argumenty wybranego przez nas typu. W tym momenciezostanie przeładowany operator +.

Na czym to polega ?

Page 2: Przeciążanie operatorów

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)

Page 3: Przeciążanie operatorów

Przeciążanie operatorów

• 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;• }• };

Ten przykład obrazuje w jaki sposób możemy przeciążyć operator ‘’+’’ lub jakikolwiek inny.

Page 4: Przeciążanie operatorów

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.

Page 5: Przeciążanie operatorów

Przeciążanie operatorów

//Manipulowanie łańcuchami w c:

char napis[10];napis = „Tekst”; //błądstrcpy(napis, „Tekst”); //poprawnie

Operator przypisania „=”

Page 6: Przeciążanie operatorów

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.

Page 7: Przeciążanie operatorów

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;}

Przykład przeciążenia operatora przypisania „=”

Page 8: Przeciążanie operatorów

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;}

Przykład przeciążenia operatora indeksowania „[ ]”

Page 9: Przeciążanie operatorów

Przeciążanie operatorówUwagi:

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żeniea+b*czawsze będzie wykonywane jako a+(b*c)a nie jako(a+b)*c

Page 10: Przeciążanie operatorów

Przeciążanie operatorów4.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 // dobrze5. A oto lista operatorów które można przeciążać:

+ - * / % ^ & | - ! = < > += -= /= %= ^= &= |= <<>> >>= <<= == != <= >= && || ++ -- , ->* -> () []

Page 11: Przeciążanie operatorów

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.

Page 12: Przeciążanie operatorów

• 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.

Page 13: Przeciążanie operatorów

• 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) { } }

Page 14: Przeciążanie operatorów

• 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 doobiektu Tv - jest to odzwierciedlenie faktu skojarzenia pilota z określonym telewizorem.

Page 15: Przeciążanie operatorów

• Funkcje zaprzyjaźnioneNiezależ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 friendfriend void wyswietl(punkt*);friend void wyswietl(punkt, char); friend void wyswietl();

};

Page 16: Przeciążanie operatorów

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";

}

Page 17: Przeciążanie operatorów

• Funkcje zaprzyjaźnione z wieloma klasamiNiezależ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

class Punkt{ static int ile_punktow;

float x, y; public:

friend void wyswietl(kolo&); // deklaracja friend}; class Kolo { static int ile_kol; float promien; punkt srodek; public:

friend void wyswietl(kolo&);}; // deklaracja friend

Page 18: Przeciążanie operatorów

• 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.

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

Page 19: Przeciążanie operatorów

• 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ącaclass Pilot {….};class Tv {…..};