Operatory

11
OP C++ - operatory 1 Operatory s 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); 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 a definiować operatory dla: - * / % & | ! itd. < > += itd. >> && || ++ -- itd. ( ) new delete można zmienić arności ani priorytetów operatorów. ratory są z definicji przeciążone.

description

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

Transcript of Operatory

Page 1: Operatory

OOP C++ - operatory 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.

Page 2: Operatory

OOP C++ - operatory 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ć albojednoargumentową funkcją składową (niejawnym pierwszymargumentem 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;

}

Page 3: Operatory

OOP C++ - operatory 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.

Page 4: Operatory

OOP C++ - operatory 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 pairint max, free; // free - pierwsze wolne miejsce

public:assoc_array (int); // konstruktorint& operator [ ] (char *); // ma dać drugi element paryvoid 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

Page 5: Operatory

OOP C++ - operatory 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;

}

Page 6: Operatory

OOP C++ - operatory 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 tablicaint 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;}

Page 7: Operatory

OOP C++ - operatory 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;

}

Page 8: Operatory

OOP C++ - operatory 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ącyString(int integer_to_convert);String(float float_to_convert);~String() { }

// Funkcje implementujące operacjesize_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);

// OperatoryString& 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; } // konwersjafriend ostream& operator<< (ostream& os, String& a_string);

private:char* character_array;size_t string_length;

};

Page 9: Operatory

OOP C++ - operatory 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;}

Page 10: Operatory

OOP C++ - operatory 10

String::String(char* new_string)

{

character_array = strdup(new_string);

string_length = strlen(character_array);

}

Page 11: Operatory

OOP C++ - operatory 11

Niebezpieczna czwórka

• Konstruktor bezargumentowy

• Konstruktor kopiujący

• Destruktor

• Operator przypisania