1 / 11

Operatory

Operatory. class complex { private: double re, im; public: complex (double r, double i = 0) { re = r; im = i; } friend complex operator+ (complex, complex); friend complex operator*(complex, complex); complex& operator += (complex); }; void f() { complex a = complex (1.3, 4);

mac
Download Presentation

Operatory

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. Operatory • class complex { • private: • double re, im; • public: • complex (double r, double i = 0) { re = r; im = i; } • friend complex operator+ (complex, complex); • friend complex operator*(complex, complex); • complex& operator += (complex); • }; • void f() • { • complex a = complex (1.3, 4); • complex b = complex(3); • complex c(0); • c = b + a; • c = b+c * a; • c = b + 10; // poprawne - nastąpi niejawna konwersja • } • Można definiować operatory dla: • + - * / % & | ! itd. • = < > += itd. • << >> && || ++ -- itd. • [ ] ( ) new delete • Nie można zmienić arności ani priorytetów operatorów. • Operatory są z definicji przeciążone.

  2. Zasada: • operator musi mieć co najmniej 1 argument będący • obiektem klasy (nie dotyczy new i delete). • Zwykle operator jest albo funkcją składową jakiejś • klasy, albo jej funkcją zaprzyjaźnioną. • Niech @ będzie dwuargumentowym operatorem. Musi być albo • jednoargumentową funkcją składową (niejawnym pierwszym • argumentem jest obiekt, w którym wykonywana jest metoda), • albo dwuargumentową funkcją zaprzyjaźnioną (pierwszy argument • jest jawny). • a @ b jest interpretowane jako a.operator@ (b) • lub operator@ (a, b) • Jeśli @ jest jednoargumentowym operatorem, • to @ a jest interpretowane jako a.operator@ () • lub operator@ (a) • complex operator+ (complex a, complex b) • { • return complex (a.re + b.re, a.im + b.im); • } • // i analogicznie operator* • inline complex& complex::operator+= (complex a) • { • re += a.re; • im += a.im; • return *this; • }

  3. Przeciążenie operatora << • class ostream { • // .... • public: • ostream& operator<< (char*); • ostream& operator<< (int i); • // ... • }; • Możemy przeciążyć ten operator. Na przykład: • class complex { • private: • double re, im; • public: • // .... • friend ostream& operator<< (ostream& os, complex& c); • }; • ostream& operator<< (ostream& os, complex& c) • { • os << “(“ << c.re << “,“ << c.im << “)”; • return os; • } • Można teraz napisać: • complex c = complex (3.5, 6.7); • cout << c; • Uwaga: operator << nie może być metodą klasy complex, ponieważ • jego pierwszym argumentem ma być strumień, a nie • obiekt complex.

  4. Przeciążanie operatora [ ] • Wyrażenie x [ i ] jest interpretowane jako x . operator [ ] ( i ). • Operator [ ] musi być funkcją składową. • Przykład: dynamiczna tablica indeksowana napisami, służąca do • zliczania słów z pliku (coś w rodzaju słownika, o kluczach będących • napisami i wartościach będących liczbami). • struct pair { • char *index; • int val; • }; • class assoc_array { • private: • ::pair *vec; // tablica par, :: bo w std też jest pair • int max, free; // free - pierwsze wolne miejsce • public: • assoc_array (int); // konstruktor • int& operator [ ] (char *); // ma dać drugi element pary • void print_all ( ); • }; • assoc_array :: assoc_array (int s) • { • max = (s > 16) ? s : 16; • free = 0; • vec = new ::pair[max]; • } • Przykład użycia: • char buf [MAX]; • assoc_array table (512); • while (cin >> word) • table [word] +; // table[word] jest referencją do val

  5. int& assoc_array :: operator [ ] (char *s) • // Szuka pary o kluczu p; jeśli nie ma, to tworzy. Zwraca referencję do • // wartości (drugiego elementu pary) • { • ::pair *pp; • for (pp = &vec [free-1]; vec <= pp; pp--) • if (strcmp (s, pp -> index) == 0) return (pp -> val); • if (free == max ) // przepełnienie • { • ::pair* nvec = new ::pair [max * 2]; • for (int i = 0; i < max; i++) • nvec [ i ] = vec [ i ]; • delete[] vec; • vec = nvec; • max = 2 * max; • } • pp = &vec [free ++]; • pp -> index = new char [strlen (s) + 1]; • strcpy ( pp -> index, s); • pp -> val = 0; • return (pp -> val); • } • void assoc_array :: print_all () • { • for (int i = 0; i < free; i++) • cout << endl << vec [i].index << “: “ << vec [i].val; • }

  6. Przeciążanie operatora () • Jest to przeciążenie wywoływania funkcji, czyli wyrażenia postaci • wyr (lista_wyr) • gdzie wyr jest pierwszym argumentem operatora (), a lista_wyr drugim. • Przykład - iterator dla assoc_array. • Do deklaracji klasy assoc_array dodajemy • friend class iterator_assoc; • class iterator_assoc { • private: • const assoc_array& tab; // iterowana tablica • int i; // bieżący indeks • public: • iterator_assoc (const assoc_array& s) : tab(s) { i = 0; } • ::pair* operator () () // operator () • { return (i < tab.free) ? &tab.vec[i++] : 0; } • }; • main () // program liczy liczbę wystąpień słów na wejściu • { • const MAX = 256; • char buf [MAX]; • assoc_array liczniki (512); • while (cin >> buf) liczniki [buf]++; • iterator_assoc nast (liczniki); // inicjalizacja iteratora • ::pair * p; • while (p = nast () ) • cout << p -> index << “: “ << p -> val << endl; • }

  7. Konwersje typów - operatory konwersji • X :: operator T () definiuje konwersję z X do T • class String { • public: • ..... • operator char* () { return tablica; } • private: • char* tablica; int dlugosc; • }; • String s = ...; • char *p = s; // konwersja z typu String do char* • Przeciążanie operatora = • Problem ten sam, co z konstruktorem kopiującym. • class Napis • { • private: • char *ptr; size_t len; • public: • Napis () { ptr = NULL; len = 0; } • // konstruktor kopiujący: • Napis (const Napis& n ) {ptr = strdup(n.ptr); len = strlen(ptr);} • Napis& operator= (const Napis& n); • virtual ~Napis () { /*if (ptr != NULL)*/ delete ptr; } • }; • Napis& Napis :: operator= (const Napis& n) • { if (this != &n) • { delete ptr; • ptr = new char [len = n.len]; • strcpy (ptr, n.ptr); • } • return *this; • }

  8. class String { • public: • // Konstruktory/Destruktory • String() • {character_array = new char[1]; character_array[0] = '\0';} • String(char* new_string); • String(String& new_string); // konstruktor kopiujący • String(int integer_to_convert); • String(float float_to_convert); • ~String() { } • // Funkcje implementujące operacje • size_t size() {return string_length;} • String& copy(); • int as_integer(); • float as_float(); • String& read_up_to (char delimiter); • String& break_at (char delimiter); • bool contains_string (char* a_character_array); • int locate_string (char* a_character_array); • String& copy_sequence (int sequence_start, int sequence_end); • // Operatory • String& operator+ (String& a_string); • String& operator+= (String& a_string); • String& operator= (String& a_string); • String& operator= (const char* a_character_array); • int operator< (String& a_string); • int operator> (String& a_string); • int operator== (String& a_string); • operator char* () {return character_array; } // konwersja • friend ostream& operator<< (ostream& os, String& a_string); • private: • char* character_array; • size_t string_length; • };

  9. String& String::operator+ (String& a_string) { size_t total_size = string_length + strlen(a_string) + 1; char* temp_array = new char[total_size]; char* char_array = a_string; strcpy(temp_array, character_array); strcat(temp_array, char_array); String* new_string = new String(temp_array); delete temp_array; return *new_string; } String& String::operator= (String& a_string) { char* new_char_array = a_string; delete character_array; character_array = new char[strlen(new_char_array) + 1]; strcpy(character_array, new_char_array); string_length = strlen(character_array); return *this; } String& String::operator= (const char* a_character_array) { delete character_array; character_array = new char[strlen(a_character_array) + 1]; strcpy(character_array, a_character_array); string_length = strlen(character_array); return *this; } int String::operator==(String& a_string) { return(strcmp(character_array, (char*) a_string) == 0); } ostream& operator<< (ostream& os, String& a_string) { os << a_string.character_array; return os; }

  10. String::String(char* new_string) { character_array = strdup(new_string); string_length = strlen(character_array); }

  11. Niebezpieczna czwórka • Konstruktor bezargumentowy • Konstruktor kopiujący • Destruktor • Operator przypisania

More Related