1. Functii virtuale. Polimorfism
2. Supraincarcarea operatorilor
Un pointer de tipul clasei de baza poate contine adrese ale unor obiecte de tipul claselor derivate. Fie de exemplu o clasa Baza
class Baza
;
si o clasa derivata
class Deriv : public Baza
;
In functia main() putem scrie
void main()
Fie f() o functie definita in clasa Baza si o functie cu acelasi nume f() definita in clasa Deriv. O instructiune de apelare a functiei f() prin po 151c23b inter duce la apelarea functiei f() definita in clasa Baza. Fie de exemplu clasa de baza
class Baza
} ;
Fie clasa derivata
class Deriv : public Baza
Consideram urmatoarea functie main()
void main()
La executia acestui program se vor afisa mesajele
se apeleaza Baza :: f()
se apeleaza Baza :: f()
In acest caz functia apelata este determinata de tipul pointerului si nu de tipul obiectului indicat de pointer.
Vom transforma functia f() in functie virtuala adaugand cuvantul virtual definitia functiei
virtual void f()
virtual void f()
La executia programului se vor afisa mesajele
se apeleaza Baza :: f()
se apeleaza Deriv :: f()
In cazul functiilor virtuale functia apelata este determinata de tipul obiectului indicat de pointer.
Probleme rezolvate
Problema 1. Sa se defineasca o clasa de baza numita Persoana ce contine un camp nume cu numele persoanei si o functie print() ce afisaza numele. Functia print() va fi virtuala. Definitia clasei este cea de mai jos.
class Persoana
virtual void print()
};
Sa se defineasca o clasa numita Angajat ce mosteneste clasa Persoana. Clasa va contine un camp cu numele departamentului si o functie print() ce va afisa numele angajatului si numele departamentului. Definitia clasei este cea de mai jos.
class Angajat : public Persoana
virtual void print()
Sa se defineasca o clasa numita Manager ce mosteneste clasa Angajat. Clasa va contine un camp cu pozitia managerului si o functie print() ce va afisa numele, departamentul si pozitia managerului. Definitia clasei este cea de mai jos.
class Manager : public Angajat
virtual void print()
};
Se vor crea obiecte cu angajati si manageri si se vor afisa datele acestora (numele, departamentul si pozitia manageriala). Programul de rezolvare a problemei este prezentat mai jos.
int main()
Observatii. Se va explica de ce functia print() trebuie sa fie virtuala.
Rezultatele rularii programului sunt cele de mai jos.
2. Supraincarcarea operatorilor
Operatorii limbajului C++ sunt automat definiti pentru tipurile fundamentale: int, double, char, etc. Cand definim o clasa noua, cream un nou tip. Operatorii limbajului pot fi definiti si pentru tipurile nou create. Aceasta operatie se numeste supraincarcarea operatorilor (operator overloading).
2.1.Supraincarcarea operatorilor aritmetici
Pentru a supraincarca un operator definim o functie de forma
tip operator semn (parametri)
unde semn este operatorul dorit +,-, *, / , [], (), <<, >>, =, etc. Operatorii supraincarcati au aceeasi prioritate ca cei originali si acelasi numar de parametri. Mentionam ca orice operator arithmetic supraincarcat poate fi definit ca functie membra a clasei sau ca functie globala.
Supraincarcarea operatorilor << si >>
Operatorul << este numit operator de insertie, el insereaza caractere intr-un stream. Operatorul >> este numit operator de extractie, el extrage caractere dintr-un stream.
Toate functiile de insertie au forma
ostream& operator << (ostream& stream, tip obiect)
Primul parametru este o referinta la streamul de iesire. Al doilea este obiectul ce trebuie inserat. Ultima instructiune este
return stream;
Operatorul de extractie >> este supraincarcat astfel
friend istream& operator >> (istream& stream, tip& obiect);
Operatorii << si >> pe care i-am definit nu pot fi membri ai clasei deoarece operandul stang ostream, respectiv istream nu este un membru al clasei. In consecinta, acesti operatori vor fi functii externe.
Probleme rezolvate
Problema 2. Se va construi o clasa Complex pentru lucrul cu numere complexe. Partea reala si partea imaginara a numarului complex sunt memorate in doua variabile de tip double, denumite real si imag. Se vor defini :
Programul de rezolvare a problemei este cel de mai jos.
# include <iostream.h>
class Complex
Complex operator Complex);
Complex operator Complex);
Complex::Complex(double x, double y)
Complex Complex::operator+(Complex p)
ostream& operator<< (ostream& stream, const Complex& x)
Complex Complex::operator = (Complex a)
Complex operator-(Complex& x, Complex& y)
int main()
Rezultatele rularii programului sunt cele de mai jos.
Probleme propuse
Problema 1 In programul anterior se va decomenta instructiunea
c = a = b;
pentru a verifica functionarea operatorului =.
Problema 2. Se vor declara variabilele clasei, real si imag, ca fiind private. Se vor declara operatorii - si << ca functii prietene pentru a avea acces la variabilele private ale clasei.
Problema 3. Se va declara operatorul - ca functie membra a clasei.
Problema 4. Se va declara operatorul + ca functie globala.
|