- •Programare orientată pe obiecte
- •§1. Principiile programării orientate pe obiecte.
- •§3. Constructori şi destructori.
- •8) Aceste mesaje apar după ce se termină lucrul programului.
- •§4. Operaţii de intrare/ieşire a informaţiei.
- •§5. Moştenire simplă.
- •§6. Moştenire multiplă
- •§7. Moştenirea pe mai multe niveluri. Clase virtuale
- •§9. Definirea şi utilizarea referinţelor
- •§10. Tablouri de obiecte. Pointeri şi referinţe la obiecte. Pointeri la membrii clasei
- •§11. Dirijarea dinamică a memoriei
- •§12. Constructor de copiere
- •§13. Funcţii prietene şi clase prietene
- •§14. Supraîncărcarea operatorilor
- •§15. Supraîncărcarea operatorilor prin funcţii prietene
- •§16. Supraîncărcarea unor operatori speciali
- •Operatorii de incrementare şi decrementare
- •Operatorii de inserţie şi extragere
- •Operatorul indice
- •Operatorul funcţie
- •Operatorii new şi delete
- •Operatorul virgulă
- •Operatorul de conversie
- •§17. Funcţii-şablon şi clase-şablon
- •§18. Realizarea conceptului de polimorfism
- •§19. Clase abstracte
- •§20. Membrii statici ai clasei
- •§23. Tratarea excepţiilor
- •Bibliografie
Operatorii new şi delete
Operatorii new şi delete pot fi supraîncărcaţi pentru o anumită clasă, dar pot fi supraîncărcaţi şi la nivel global. Fiind supraîncărcaţi la nivelul unei clase, i-şi schimbă specificul acţiunii doar în raport cu clasa dată, iar la nivel exterior îşi păstrează modul de executare. La nivel de clasă operatorii daţi pot fi supraîncărcaţi doar prin metoda funcţiilor membre. De asemenea, trebuie de ţinut cont de faptul că operatorii daţi au două forme, una pentru variabile simple new, delete şi alta pentru tablouri new[], delete[]. Pentru a realiza supraîncărcarea, în clasă sunt incluse următoarele prototipuri:
class nume_cl
{
. . .
void *operator new (size_t dim);
void operator delete (void *adr);
void *operator new[] (size_t dim);
void operator delete[] (void *adr);
. . .
}
Cea mai simplă formă de supraîncărcare ar putea fi oferită de următoarele implementări ale funcţiilor:
void *nume_cl :: operator new (size_t dim)
{
return malloc (dim);
}
void nume_cl :: operator delete (void *adr)
{
free (adr);
}
void *nume_cl :: operator new[] (size_t dim)
{
return malloc (dim);
}
void nume_cl :: operator delete[] (void *adr)
{
free (adr);
}
(nu prea are sens să supraîncărcăm aceşti doi operatori)
Operatorul virgulă
Operatorul virgulă (,) poate fi supraîncărcat atât prin metoda funcţiilor prietene, cât şi prin metoda funcţiilor membre. Este un operator binar şi nu prezintă vre-o excepţie de la regulile generale în ceea ce priveşte numărul de parametri fictivi ai funcţiilor ce realizează supraîncărcarea: deci un parametru fictiv la supraîncărcare prin metoda funcţiilor membre şi doi parametri la supraîncărcare prin metoda funcţiilor prietene. Pentru a exemplifica, se va face referire la clasa complex. În această clasă, vor fi introduse următoarele prototipuri de funcţii:
class complex
{
. . .
complex operator ,(complex c);
friend complex operator ,(complex c, float f);
. . .
};
În continuare, urmează o implementare a acestor funcţii:
funcţia membru
complex complex :: operator , (complex c)
{
return c;
}
funcţia prieten
complex operator , (complex c, float f)
{
complex cf(f,0);
return cf;
}
Ambele funcţii realizează logica operatorului virgulă, adică valoarea oferită de operator este valoarea celui de al doilea operand, valoarea primului operand fiind ignorată.
Operatorul de conversie
Este cunoscut faptul că acţiunea de trecere a unor date de un anumit tip la alt tip de date reprezintă esenţa operatorului de conversie, care este un operator unar. Acest operator, de asemenea, poate fi supus acţiunii de supraîncărcare în cadrul unei clase. Ideea supraîncărcării acestui operator în cadrul clasei date va fi de a transforma obiectele obţinute în baza clasei date la alt tip de date. Supraîncărcarea operatorului de conversie poate fi făcută doar prin metoda funcţiilor membri. Funcţia care realizează supraîncărcarea nu are specificat tipul valorii returnate, cu toate că după logică ea totuşi returnează o valoare. În schimb, numele operatorului este chiar tipul valorii returnate. Deci clasa, care realizează una sau mai multe conversii, va conţine unul sau mai multe prototipuri de următorul fel:
class nume_cl
{
. . .
operator tip ();
. . .
}
Exemplu. De alcătuit un program în care este implementată clasa lungime, realizând supraîncărcarea unui operator de conversie.
#include<iostream.h>
#include<conio.h>
class lungime
{
int metri;
int centimetri;
public:
lungime (int m, int c)
{
metri=m;
centimetri=c;
}
operator float ()
{
return (metri+centimetri/100.0);
}
};
//==========
void main()
{
lungime L1(3, 20), L2(7, 86);
cout << float(L1) << ’ ’ << float(L2) << endl;
getch();
}
Din exemplu se vede, că în cadrul clasei lungime a fost efectuată supraîncărcarea operatorului de conversie la tipul float şi drept rezultat lungimile L1 şi L2 vor fi afişate sub forma 3.2 şi 7.86.
