You are on page 1of 12

Valeriu Iorga Suprancrcarea operatorilor.

1. Suprancrcare. 2. Funcii prieten. 3. Modaliti de suprancrcare a operatorilor. 4. Operatori redefinii ca funcii prieten. 5. Operatori redefinii ca funcii membri. 6. Suprancrcarea operatorului de atribuire. 7. Suprancrcarea operatorului de indexare. 8. Suprancrcarea operatorilor new i delete. 9. Suprancrcarea operatorului apel de funcie. 10. Suprancrcarea operatorilor de conversie. 11. Suprancrcarea operatorilor << i >>. 12. Probleme.

Programare n C / C++

Operatorii sunt notaii concise, infixate, pentru operaii matematice uzuale. Limbajul C++, ca orice limbaj de programare asigur un set de operatori pentru tipurile primitive. n plus, fa de limbajul C, C++ ofer posibilitatea asocierii operatorilor existeni cu tipurile definite de utilizator . Astfel, prezint interes extinderea operatorilor n aritmetic complex, algebra matricial, n lucrul cu iruri de caractere, etc. Un operator poate fi privit ca o funcie, n care termenii sunt argumentele funciei (n lipsa operatorului +, expresia a+b s-ar calcula apelnd funcia aduna(a,b)). Limbajul C++ introduce urmtorii operatori noi: new i delete- pentru gestiunea memoriei dinamice, operatorul de rezoluie (::) i operatorii de acces la membri: .* i ->*. 1. Suprancrcare. Prin suprancrcarea unui operator, acesta este utilizat n contexte diferite, avnd aceeai semnificaie sau o semnificaie diferit. Astfel operatorul + este suprancrcat pentru adunarea ntregilor i a realilor; operatorul << este suprancrcat cu semnificaia de deplasare la stnga, dac termenii sunt ntregi sau inserare n flux, dac un termen este un flux de date, iar cellalt un obiect. Programatorul poate asocia noi semnificaii operatorilor existeni prin suprancrcarea operatorilor. Vom evita folosirea termenului redefinire, cruia i vom da o semnificaie diferit, n contextul motenirii. Anumii operatori pot fi utilizai cu orice tip de termeni (sunt deja suprancrcai global de ctre compilator). Acetia sunt: new, delete, sizeof, ::, =, &, ->*, .*, ., ->. Pot fi suprancrcai urmtorii operatori: + += && new -= || * / *= ++ % /= -^ %= ->* & | ~ ^= , &= -> ! = |= << < >>= >> > <<= [] () == != <= >=

new[]

delete

delete[]

Nu pot fi suprancrcai operatorii: ::, ., .*, ?:, sizeof. Setul de operatori ai limbajul C++ nu poate fi extins prin asocierea de semnificaii noi unor caractere, care nu sunt operatori de exemplu nu putem defini operatorul **). Prin suprancrcarea unui operator nu i se poate modifica aritatea (astfel operatorul ! este unar i poate fi redefinit numai ca operator unar. De asemeni asociativitatea i precedena operatorului se menin. La suprancrcarea unui operator nu se pot specifica argumente cu valori implicite. Operatorii suprancrcai ntr-o clas sunt motenii n clasele derivate (excepie face operatorul de atribuire =). Semntura unei funcii n care se suprancarc un operator este: tip_rezultat operator#(list_argumente);

Valeriu Iorga

Programare n C / C++

2. Funcii prieten. n afara funciilor membre, datele private i cele protejate mai pot fi accesate de funciile prieten (friend) ale clasei. O funcie este considerat prieten al unei clase, dac declararea funciei precedate de specificatorul friend, apare n declararea clasei,. Definiia funciei prieten se face global, n afara clasei. Dac o funcie are ca parametri obiecte aparinnd la dou clase diferite, atunci ea poate fi declarat ca funcie membru a unei clase i prieten al celeilalte clase, sau ca funcie prieten ambelor clase. De exemplu fie o funcie de nmulire a unei matrice cu un vector. Parametrii funciei vor fi dou obiecte o matrice i un vector. Clasele respective Mat i Vec pot declara fiecare, funcia MatVec() ca prieten: class Mat{ int n; double **m; public: Mat(); Mat(Mat&); . . . friend Vec MatVec(Mat&, Vec&); }; class Vec{ int n; double *v; public: Vec(); Vec(Vec&); . . . friend Vec MatVec(Mat&, Vec&); }; De asemenea funciile prieten se utilizeaz n contextual suprancrcrii operatorilor. Declararea unei funcii prieten poate fi fcut n orice parte a clasei (public, privat sau protejat). O funcie prieten a unei clase poate accesa toi membrii clasei. Dac o clas este prieten cu alt clas, membrii ei pot accesa membrii celeilalte clase. 3. Modaliti de suprancrcare a operatorilor. O funcie operator suprancrcat poate fi introdus ca funcie membr (n general nestatic) sau funcie prieten (funcie nemembr). Declararea unei funcii membr nestatic specific urmtoarele: 1) funcia poate accesa partea privat a declaraiei clasei 2) funcia este n domeniul clasei 3) funcia trebuie apelat dintr-un obiect O funcie membr static satisface numai primele dou condiii, n timp ce o funcie prieten a unei clase satisface numai prima condiie. O funcie operator avnd ca prim argument un tip primitiv nu poate fi funcie membru. Funciile care modific reprezentarea unui obiect necesit acces la datele membri, deci trebuie s aparin clasei. Ele sunt funcii membrecu argumente referine neconstante. Dac se doresc conversii implicite pentru termenii funciei operator, aceasta va fi funcie nemembr cu argumente referine constante. Aceste funcii implementeaz operatorii care nu necesit operanzi L-valori (adic se aplic tipurilor fundamentale). Acetia sunt n general operatorii binari. Necesitatea accesului la reprezentare determin definirea lor ca funcii prieten.

Valeriu Iorga

Programare n C / C++

Operatorii care produc o nou valoare din valorile argumentelor (de exemplu operatorul +) se definesc n afara clasei. Dac nu sunt necesare conversii de tip, alegerea ntre funcie membru i funcie prieten rmne la latitudinea programatorului. O funcie nemembr folosete numai argumente explicite, n timp ce o funcie membr folosete argumentul implicit this. Argumentele clase, transmise prin valoare se copiaz n stiv neeconomic. Se prefer n acest caz argumentele referine constante. Dac valoarea ntoars de funcie este o referin, atunci aceasta nu poate fi o variabil automatic (local funciei). Ea nu poate fi nici o variabil static local, deoarece operatorul poate fi folosit de mai multe ori ntr-o expresie. Valoarea de ntoarcere trebuie s fie alocat n memoria liber (heap) sau s fie preluat dintr-un buffer de obiecte statice. ntoarcerea unei referine la obiectul modificat se realizeaz prin return *this. Se caut minimizarea numrului de funcii care au acces la reprezentarea intern a unei clase, prevzndu-se funcii de acces. n mod obligatoriu sunt funcii membre: constructorii, destructorii, funciile virtuale, etc. 4. Operatori suprancrcai ca funcii prieten. Operatorii folosii n mod uzual pot fi unari sau binari. Utilizarea unui operator binar sub forma a#b este interpretat ca operator#(a,b) Aadar, un operator binar va fi reprezentat printr-o funcie nemembr cu dou argumente, iar un operator unar, printr-o funcie nemembr cu un singur argument. Argumentele se iau clase sau referine constante la clase (pentru o preluare economic, asigurnd protecia datelor) Vom exemplifica pentru clasa Cplx: class Cplx{ double re, im; public: Cplx(double x=0, double y=0); Cplx(const Cplx& z); //operatori friend Cplx friend Cplx friend Cplx friend Cplx binari operator+(const operator-(const operator*(const operator/(const Cplx& Cplx& Cplx& Cplx& s, s, s, s, const const const const Cplx& Cplx& Cplx& Cplx& d); d); d); d);

//operatori de comparatie friend int operator==(const Cplx& s, const Cplx& d); friend int operator!=(const Cplx& s, const Cplx& d); //operatori unari friend Cplx operator-(const Cplx& z); friend Cplx operator!(const Cplx& z); //conjugat friend Cplx& operator++(Cplx& z); //prefix friend Cplx operator-(Cplx& z,int); //postfix }; //definitii operatori n afara domeniului clasei Cplx operator+(const Cplx& s, const Cplx& d){ return Cplx(s.re+d.re,s.im+d.im); }; Cplx operator-(const Cplx& s, const Cplx& d){ return Cplx(s.re-d.re,s.im-d.im); };

Valeriu Iorga

Programare n C / C++

Cplx operator*(const Cplx& s, const Cplx& d){ return Cplx(s.re*d.re-s.im*d.im,s.re*d.im+s.im*d.re); }; Cplx operator/(const Cplx& s, const Cplx& d){ double t=d.re*d.re+d.im*d.im; return Cplx((s.re*d.re+s.im*d.im)/t , (s.im*d.re-s.re*d.im)/t); }; int operator==(const Cplx& s, const Cplx& d){ return s.re==d.re && s.im==d.im; }; int operator!=(const Cplx& s, const Cplx& d){ return s.re!=d.re || s.im!=d.im; }; Cplx operator-(const Cplx& z){ return Cplx(-z.re, -z.im); }; Cplx operator!(const Cplx& z){ return Cplx(z.re, -z.im); }; Cplx& operator++(Cplx& z){ return Cplx(z.re+1, z.im); }; Cplx operator++(Cplx& z,int){ Cplx t(z); z.re+=1; return t; }; //prefix

//postfix

Pentru a face deosebirea ntre semnturile funciilor operatori de incrementare prefix i postfix s-a introdus un argument fictiv pentru cel din urm. Incrementarea prefix ntoarce valoarea incrementat, deci trebuie s fie o L-valoare (rezultatul ntors va fi o referin), n timp ce postincrementarea ntoarce valoarea dinaintea incrementrii. 5. Operatori suprancrcai ca funcii membri. Funciilor membru li se transmite un argument implicit (ascuns) this (adresa obiectului, care poate reprezenta primul termen), motiv pentru care un operator binar poate fi implementat printr-o funcie membru nestatic cu un singur argument (termenul din dreapta operatorului). a#b este interpretat ca a.operator#(b) O funcie membru operator unar ca o funcie membru nestatic fr argumente ( #a se interpreteaz ca a.operator#(); pentru operatorul postfixat a# convenia este a.operator#(int) ). n acest context, operatorii clasei Cplx se scriu: Class Cplx{ double re, im; public: Cplx operator+(const Cplx& d); Cplx operator-(const Cplx& d); Cplx operator*(const Cplx& d); Cplx operator/(const Cplx& d); Cplx& operator+=(const Cplx& d); Cplx& operator-=(const Cplx& d); Cplx& operator*=(const Cplx& d); Cplx& operator/=(const Cplx& d);

Valeriu Iorga
int operator==(const Cplx& d); int operator!=(const Cplx& d); Cplx& operator-(); Cplx& operator!(); Cplx& operator++(); Cplx operator++(int); }; Cplx Cplx::operator+(const Cplx& d){ return Cplx(re+d.re, im+d.im); }; Cplx Cplx::operator-(const Cplx& d){ return Cplx(re-d.re, im-d.im); }; Cplx Cplx::operator*(const Cplx& d){ return Cplx(re*d.re-im*d.im, re*d.im+im*d.re); };

Programare n C / C++

Cplx Cplx::operator/(const Cplx& d){ double t=d.re*d.re+d.im*d.im; return Cplx((re*d.re+im*d.im)/t, (im*d.re-re*d.im)/t); }; Cplx& Cplx::operator+=(const Cplx& d){ if(this!=&d){ re+=d.re; im+=d.im; }; return *this; }; Cplx& Cplx::operator-=(const Cplx& d){ if(this!=&d){ re-=d.re; im-=d.im; }; return *this; }; Cplx& Cplx::operator*=(const Cplx& d){ if(this!=&d){ double t=re; re=re*d.re-im*d.im; im=t*d.im+im*d.re; }; return *this; }; Cplx& Cplx::operator/=(const Cplx& d){ if(this!=&d){ double t1=re, t2=d.re*d.re+d.im*d.im; re=(re*d.re+im*d.im)/t2; im=(im*d.re-t1*d.im)/t2; }; return *this; }; int Cplx::operator==(const Cplx& d){ return re==d.re && im==d.im; }; int Cplx::operator!=(const Cplx& d){ return re!=d.re || im!=d.im;

Valeriu Iorga
}; Cplx& Cplx::operator-(){ re=-re; im=-im; return *this; }; Cplx& Cplx::operator!(){ im=-im; return *this; }; Cplx& Cplx::operator++(){ re++; return *this; }; Cplx Cplx::operator++(int){ Cplx t(re,im); re++; return t; }; 6. Suprancrcarea operatorului de atribuire.

Programare n C / C++

Operaia de atribuire simpl, dac nu este suprancrcat, realizeaz o copiere membru cu membru. Pentru obiectele care nu conin date alocate dinamic la iniializare, atribuirea prin copiere membru cu membru funcioneaz corect, motiv pentru care nu se suprancarc operatorul de atribuire. Pentru clasele ce conin date alocate dinamic, copierea membru cu membru, executat n mod implicit la atribuire conduce la copierea pointerilor la datele alocate dinamic, n loc de a copia datele. Operatorul de atribuire poate fi redefinit numai ca funcie membr, el fiind legat de obiectul din stnga operatorului =, o L-valoare, motiv pentru care va ntoarce o referin la obiect. O prim cerin la scrierea funciei operator= este evitarea autoatribuirii a=a. n acest scop se efectueaz testul this != &d (unde d este parametrul funciei -obiectul din dreapta operatorului = . Urmeaz apoi curirea membrului stng (eliberarea memoriei alocate dinamic). Copierea propriu zis este fcut de obicei folosind constructorul de copiere. Funcia operator returneaz o referin la obiectul modificat (return *this). Exemplificm pentru clasa String, definit astfel: class String{ char* s; int n; public: String(); //c(onstruc)tor implicit String(const char* p); //ctor de initializare String(const String& r); //cr de copiere ~String(); //dtor String& operator=(const String& d); String& operator=(const char* p); }; //ctor de copiere String::String& operator=(const String& d){ if(this != &d){ //evitare autoatribuire if(s) //curatire delete [] s;

Valeriu Iorga
n=d.n; //copiere s=new char[n]; strncpy(s, d.s, n); //intoarce obiectul modificat

Programare n C / C++

};

}; return *this;

//ctor de initializare (cu un sir tip C) String::String& operator=(const char* p){ if(s) delete [] s; n=strlen(p); s=new char[n]; strncpy(s, p, n); return *this; }; 7. Suprancrcarea operatorului de indexare. Operatorul de indexare este un operator binar, avnd ca prim termen obiectul care se indexeaz, iar ca al doilea termen indicele: obiect [ indice ] i este interpretat ca: obiect.operator[ ](indice) . Funcia operator de indexare trebuie s fie funcie membr nestatic. Primul termen, transmis implicit prin this este obiectul asupra cruia se execut indexarea. Argumentul funciei reprezint indicele, care poate fi de orice tip, spre deosebire de indicii predefinii i este al doilea termen din operator. Valoarea ntoars de funcia operator este o referin la elementul indexat din obiect. Exemplificm cu operatorul de indexare pentru clasa String: class String{ int n; char* s; public: . . . char& operator[](int); }; char& String:: operator[](int i){ if(i>=0 && i<n) return s[i]; else return 0; }; 8. Suprancrcarea operatorilor new i delete. Operatorii new i delete pot fi suprancrcai ca funcii operatori membre statice. Funcia operator new are semntura: void* operator new(size_t); Operatorul redefinit apeleaz constructorul clasei dup alocarea dinamic pe care o realizeaz. Funcia operator delete are semntura: void operator delete(void*); unde parametrul este un pointer la obiectul eliminat. Operatorul redefinit delete apeleaz ntotdeauna destructorul clasei nainte de a elibera memoria alocat dinamic. Dac n clasa C se suprancarc operatorul new, atunci versiunea furnizat de sistem se obine prin C *p = ::new C(); Exemplu1:Suprancrcai operatorul new, astfel nct s iniializeze memoria alocat la 0. void* C::operator new(size_t dim){ void *p = new char[dim]; return memset(p, 0, sizeof(C)); }

Valeriu Iorga

Programare n C / C++

Exemplu1:Suprancrcai operatorul new[], astfel nct s iniializeze memoria alocat la o valoare dat ca parametru. void* C::operator new[](size_t dim, unsigned v){ int n = dim / sizeof(C); C *p = ::new C[n]; for(int i=0; i<n; i++) p[i].val = v; //clasa are data membra val return p; } 9. Suprancrcarea operatorului apel de funcie. Apelul unei funcii este o construcie de forma: nume_functie(lista_argumente); desemnnd operatorul binar() aplicat celor doi termeni nume_functie i lista_argumente. Numele funciei poate fi nlocuit printr-un pointer la funcie: (*pf)(lista_argumente); Funcia operator redefinit apel de funcie va avea aadar 2 parametri: un obiect i o list de argumente. Implementat ca funcie membr nestatic, primul parametru este transmis implicit, astfel c un apel de forma: obiect(lista_argumente); este interpretat ca: obiect.operator()(lista_argumente); Suprancrcarea operatorului () se utilizeaz la definirea functorilor (obiecte funcii). Un functor este un obiect pentru care se suprancarc operatorul apel de funcie ( operator()()) i care se comport ca o funcie. n mod uzual obiectele funcii se folosesc n locul pointerilor la funcii. Funciile inline nu pot folosi ca parametri pointeri la funcii (care sunt apelai indirect), ci obiecte funcii. Operatorul apel de funcie asigur o sintax uniform pentru obiectele care se comport ca i funciile. Algoritmii generici din STL au printre argumente i o biecte funcii. Acestea pot fi: - generatori = functori fr argumente - funcii unare = functori cu un argument - funcii binare = functori cu dou argumente. O funcie unar boolean este un predicat, n timp ce o funcie binar boolean este un predicat binar. De exemplu, pentru o dreapt, definit prin tietura n origine i pant putem defini clasa: class Dreapta{ double m,y0; public: Dreapta(double m1=1, double y01=0): m(m1),y0(y01){} //ctor double operator()(double x){ return y0+m*x; } //functor }; Clasa va fi folosit ntr-o funcie main() astfel: Dreapta d1; Dreapta d2(2., 3.); double y1=d1(5.5); double y2=d2(1.5);

//y1=5.5 //y2=2*1.5+3=6

Definii un obiect funcie (functor) care genereaz termenul de rang n din irul lui Fibonacci.
class Fibo{ public: Fibo():x(0),y(1){}; //constructor long operator()(int n); //supraincarcare operator functie

Valeriu Iorga
private: long x, y; }; long Fibo::operator ()(int n){ for(int i=2; i<=n; i++){ long z=x+y; x=y; y=z; }; return x; };

Programare n C / C++

10. Suprancrcarea operatorilor de conversie. n C++ la evaluarea unei expresii se efectueaz conversii implicite pentru tipurile predefinite. Deoarece nu exist conversii implicite de la o clas la un tip predefinit, programatorul i poate defini conversii explicite prin suprancrcarea unui operator de conversie al clasei. Astfel pentru clasa C, funcia membru nestatic de conversie C::operator T() unde T este un nume de tip primitiv realizeaz conversia de la tipul C la tipul T. Aceasta nu specific nici un tip de rezultat ntors, deoarece se returneaz implicit valoarea obiectului convertit la tipul pentru care este definit conversia i nu are parametri. Funcia operator primete ca prim parametru implicit adresa obiectului i ntoarce valoarea convertit de tipul numelui funciei operator de conversie. Apelul explicit al funciei de conversie de la un obiect din clasa C la tipul primitiv T se specific prin T(obiect) sau (T) obiect. Pentru conversia unui obiect ntre dou clase C1 i C2,C1->C2 se definete funcia membru operator de conversie C1::operator C2(); Pentru ca aceast funcie s aib acces la membrii clasei C2, se declar funcie prieten clasei C2. Sunt premise astfel conversii ntre o clas i un tip predefinit sau ntre dou clase, dar nu de la un tip predefinit la o clas. Constructorii cu un singur argument pot fi folosii ca funcii de conversie de la tipul argumentului la clasa constructorului. Acest efect nu este ntotdeauna dorit, i pentru a-l evita, constructorul se declar precedat de cuvntul cheie explicit. Dac o metod a unei clase folosete parametri care sufer conversii implicite, metoda se va defini ca funcie prieten, nu ca funcie membr. Definim ca exemplu clasa Inch: class Inch{ double inch; double cm; public: explicit Inch(double i=0.) : inch(i){}; //ctor void Inch_cm(){ cm=2.54*inch;}; operator int() const {return int(inch+0.5);}; //fctie conversie } 11. Suprancrcarea operatorilor << i >>. Operatorii de intrare / ieire pot fi suprancrcai. Operatorul de extracie >>, membru al clasei istream servete pentru extragerea datelor de tipuri predefinite din fluxul de intrare cin. Prin suprancrcarea operatorului putem extrage din fluxul de intrare f, obiecte ob, scriind f >> ob; Funcia operator corespunztoare are semntura: istream& operator >> (istream& f, clasa & ob);

Valeriu Iorga

Programare n C / C++

Operatorul de inserie <<, membru al clasei ostream servete pentru depunerea datelor de tipuri predefinite n fluxul de ieire cout. Suprancrcarea operatorului permite depunerea de obiecte ob n fluxul de ieire f cu f << ob; ostream& operator << (ostream& f, const clasa & ob); ntruct ambele funciile operatori ntorc referine la fluxuri (prin return f), operatorii pot fi nlnuii.(f << o1 << o2;) Funciile operator pentru suprancrcarea operatorilor de intrare / ieire se declar funcii prieten al clasei care interacioneaz cu fluxul. Exemplificm cu clasele Cplx i String: class Cplx{ double re,im; public: friend ostream& operator<<(ostream& os, const Cplx& z); friend istream& operator>>(istream& is, Cplx& z); }; ostream& operator<<(ostream& os, const Cplx& z){ os << ( << z.re <<, << z.im << ) << endl; return os; }; istream& operator>>(istream& is, Cplx& z){ is >> z.re >> z.im; return is; }; class String{ int n; char *s; public: . . . friend ostream& operator<<(ostream&os,const String& w); friend istream& operator>>(istream& is, String& w); }; ostream& operator<<(ostream& os,const String& w){ for(int i=0; i<w.n; i++) os << w.s[i]; return os; }; istream& operator>>(istream& is, String& w){ char zona[100]; is.get(zona,100); w=zona; return is; }; 12. Probleme. 1. O expresie ptratic de o variabil are forma: ax2+bx+c n care numerele a,b,c (coeficienii) au valori fixate, iar variabila x poate lua diferite valori. Specificai,proiectai i implementai clasa Patrat, care poate pstra informaii asupra unei expresii ptratice. Un constructor implicit seteaz cei 3 coeficieni la zero. Se vor prevedea funcii membru pentru: - schimbarea coeficienilor - aflarea valorii curente a coeficienilor - evaluarea unei expresii ptratice pentru un x dat

10

Valeriu Iorga

Programare n C / C++

- determinarea numrului de rdcini reale a unei expresii ptratice Se vor redefini operatorii + i * ca funcii nemembre pentru: adunarea a dou expresii ptratice: Patrat operator +(const Patrat &p1, const Patrat &p2); - nmulirea unei expresii ptratice cu o constant Patrat operator *(double k, const Patrat &p); 2. Proiectai i implementai clasa Complex care s permit lucrul cu numere complexe. Constructorul clasei va avea ca argumente partea real, respectiv imaginar a numrului complex (n mod implicit aceste valori se iau 0). Se va asigura un constructor de copiere. Se vor prevedea funcii membri pentru: - accesul la partea real, respectiv imaginar a numrului complex - suprancrcarea operatorilot +=, -=, *=, /= pentru adunarea, scderea, nmulirea i mprirea numrului complex cu un alt numr complex dat ca argument - modulul numrului complex - argumentul numrului complex Se va redefini operatorul >> ca funcie prieten pentru citirea unui numr complex de la intrarea standard Se vor asigura funcii nemembru pentru: - testul de egalitate a dou numere complexe (suprancrcarea operatorului ==) - scrierea unui numr complex la ieirea standard (suprancrcarea operatorului <<) - suprancrcarea operatorilor +,-,*,/ pentru a permite operaii cu dou argumente numere complexe - suprancrcarea operatorului de atribuire 3. Proiectai i implementai clasa Raional care s permit lucrul cu numere raionale. Constructorul clasei va avea dou argumente: numratorul, respectiv numitorul numrului raional (constructorul poate avea i un singur argument,caz n care al doilea se ia implicit 1,sau nici un argument, caz n care se iau valorile implicite 0 i 1). Se va asigura un constructor de copiere. Se vor prevedea funcii membri pentru: - accesul la numratorul, respectiv numitorul numrului raional - suprancrcarea operatorilot +=, -=, *=, /= pentru adunarea, scderea, nmulirea i mprirea numrului raional cu un alt numr raional dat ca argument Se va redefini operatorul >> ca funcie prieten pentru citirea unui numr raional de la intrarea standard Se vor asigura funcii nemembre pentru: - testul de egalitate a dou numere raionale (suprancrcarea operatorului ==) - scrierea unui numr raional la ieirea standard (suprancrcarea operatorului <<) - suprancrcarea operatorilor +,-,*,/ pentru a permite operaii cu dou argumente numere raionale. - suprancrcarea operatorului de atribuire. 4. Proiectai i implementai clasa Vector care s permit lucrul cu vectori de elemente reale. Constructorul clasei va avea un argument - dimensiunea vectorului i va aloca emorie pentru vector (n lipsa argumentului se ia implicit dimensiunea 10) Se va asigura un destructor i un constructor de copiere. Se vor prevedea funcii membri pentru: - determinarea dimensiunii vectorului - determinarea lungimii vectorului - suprancrcarea operatorilor +=, -=, pentru adunarea i scderea vectorului cu un alt vector dat ca argument Se va redefini operatorul >> ca funcie prieten pentru citirea unui vector de la intrarea standard Se vor asigura funcii nemembre pentru: - testul de egalitate a doi vectori (suprancrcarea operatorului ==) - scrierea unui vector la ieirea standard (suprancrcarea operatorului <<) - suprancrcarea operatorilor +,- pentru a permite operaii cu dou argumente vectori

11

Valeriu Iorga

Programare n C / C++

- suprancrcarea operatorului * pentru a permite calculul produsului scalar a doi vectori 5. Proiectai i implementai clasa Matrice care s permit lucrul cu matrice ptrate de elemente reale. Constructorul clasei va avea un argument - dimensiunea, adic numrul de linii i de coloane al matricei, va aloca memorie pentru matrice (n lipsa argumentului se ia implicit dimensiunea 10) i va permite accesul la elementele individuale prin indexare. Se va asigura un destructor i un constructor de copiere. Se vor prevedea funcii membre pentru: - determinarea dimensiunii matricei - calculul determinantului matricii - suprancrcarea operatorilor +=, -=, *=, pentru adunarea, scderea, i nmulirea unei matrice cu o alt matrice dat ca argument - suprancrcarea operatorului /= pentru calculul inversei matricei Se va redefini operatorul >> ca funcie prieten pentru citirea unei matrici de la intrarea standard Se vor asigura funcii nemembre pentru: - testul de egalitate a dou matrice (suprancrcarea operatorului ==) - scrierea unei matrice la ieirea standard (suprancrcarea operatorului <<) - suprancrcarea operatorilor +,-,* pentru a permite operaii cu dou argumente matrice. 6. Proiectai i implementai clasa String care s permit lucrul cu iruri de caractere terminate cu nul. Constructorul clasei va avea un argument-dimensiunea adic numrul de caractere al irului i va aloca memorie pentru ir (n lipsa argumentului se ia implicit dimensiunea 80). Se va asigura un destructor i un constructor de copiere. Se vor prevedea funcii membre pentru: - determinarea lungimii irului - suprancrcarea operatorului += pentru concatenarea irului cu un alt ir dat ca argument - determinarea pozitiei primei apariii a unui ir dat ca argument n irul dat Se va redefini operatorul >> ca funcie prieten pentru citirea unui ir de caractere de la intrarea standard Se vor asigura funcii nemembre pentru: - testul de egalitate a dou iruri (suprancrcarea operatorului ==) - comparaia lexicografic a dou iruri date ca argumente (rezultat -1, 0 sau 1) - scrierea unui ir la ieirea standard (suprancrcarea operatorului <<) - suprancrcarea operatorului + pentru a permite operaia de concatenare a dou iruri date ca argumente - suprancrcarea operatorului de atribuire. - selectarea dintr-un ir a unui alt ir definit prin poziie de nceput i lungime - tergerea dintr-un ir a unui numr de caractere ncepnd cu o poziie dat.

12

You might also like