Programare Orientata Obiect Novac

188
1 LIMBAJUL C++ Programarea orientată pe obiecte

description

curs facultate anul II, profesor Novac-Ududec.

Transcript of Programare Orientata Obiect Novac

Page 1: Programare Orientata Obiect Novac

1

LIMBAJUL C++

Programarea orientată peobiecte

Page 2: Programare Orientata Obiect Novac

2

Introducere

Există limbaje concepute strict pe baza POO, ex. Simula, Smalltalk, Java;

O altă abordare - adaugarea tehnicilor POO limbajelor cu mare polularitate, ex. Pascal şi C;

C++ combină avantajele oferite de C (eficienţă, flexibilitate, portabilitate) cu avantajele oferite de POO.

Page 3: Programare Orientata Obiect Novac

3

Programarea orientată pe obiecte în C++

Scopul limbajului C++ este să permită dezvoltarea programelor complexe (peste 25.000 linii cod sursă);

C++ asigură programatorului libertatea şi controlul din C, împreună cu puterea obiectelor;

POO combină metodele programării structurate cu concepte noi;

Page 4: Programare Orientata Obiect Novac

4

C++ conţine îmbunătăţiri ale limbajului C care nu sunt direct legate de POO, cum ar fi: Tipul referinţă; Funcţii inline; Supraîncărcarea operatorilor; Operatori pentru gestionarea memoriei

libere.

Page 5: Programare Orientata Obiect Novac

5

Ce este programarea orientată pe obiecte ?

În POO se împarte o problemă în subgrupe de secţiuni înrudite, care ţin seamă atât de cod cât şi de datele corespunzătoare din fiecare grup.

Se organizează apoi, aceste subgrupe pe structuri ierarhice;

Se transformă subgrupele în unităţi de sine stătătoare, numite obiecte.

Page 6: Programare Orientata Obiect Novac

6

Toate limbajele OO au 3 caracteristici comune: încapsulare, polimorfism şi moştenire

Încapsularea este un mecanism care leagă împreună cod şi date;

Permite crearea unui obiect; Un obiect este o entitate logică care

încapsulează atât date cât şi cod care manevreză aceste date;

Când se defineşte un obiect, implicit se creează un nou tip de date !

Page 7: Programare Orientata Obiect Novac

7

Polimorfism

În POO polimorfismul se aplică metode-lor unei clase şi permite definirea unor funcţii cu acelaşi nume dar cu comportament diferit (specific);

Exemplu: metoda de calculat aria unui poligon;

Page 8: Programare Orientata Obiect Novac

8

Moştenirea

Este procesul prin care un obiect poate să preia prototipul altui obiect;

Se admite astfel conceptul de clasificare;

Exemplu: Clasa mamifer

Clasa pisica Clasa pisică birmaneză

Page 9: Programare Orientata Obiect Novac

9

Inregistrare - Clasă

În numeroase aplicaţii, este necesar să se prelucreze date grupate sub forma de înregistrări, situate fizic fie în fişiere, fie înmemoria internă.

Să considerăm, de exemplu, evidenţamaterialelor dintr-o magazie.

Fiecare material se caracterizează prin maimulte atribute, cum sunt: codul materialului, denumirea materialului, cantitatea.

Page 10: Programare Orientata Obiect Novac

10

Informaţia despre un material ar putea fi, deci, păstrată pe un formular de hârtieavând, ca exemplu, următorul conţinut:

MATERIAL Cod material: 13027522 Denumire material: Pânza albă bumbacCantitate: 127.53

Page 11: Programare Orientata Obiect Novac

11

Pentru prelucrare, aceste date sunt grupateîntr-o înregistrare de forma:

127.53Pânza albă bumbac13027522

Page 12: Programare Orientata Obiect Novac

12

Remarcăm că această structură, care se introduce în memoria calcula-torului, conţine numai datele, nu şi alteinformaţii, cum ar fi denumirile atribu-telor şi tipurile de date din fiecare câmp.

Descrierea acestei structuri se face înprogram, folosind o instrucţiune numitădeclaraţie de structură.

Forma declaraţiei depinde de sintaxalimbajului de programare utilizat.

Page 13: Programare Orientata Obiect Novac

13

In limbajul C, aceleaşi declaraţii se fac sub forma:

typedef struct{ int cod; char nume[30]; double cantitate} Material;

Material a, b, c;

Page 14: Programare Orientata Obiect Novac

14

Remarcăm că nici în Pascal, nici în C nu este predefinit un tip de date numitMaterial, dar limbajul pune la dispoziţia programatorului modalitateaprin care el poate să definească un astfel de tip.

Page 15: Programare Orientata Obiect Novac

15

Înregistrarea (engl: record) este o structură de date neomogenă cu următoarele caracteristici:

Componentele înregistrării, numite înmod uzual câmpuri (engl. fields), au fiecare propriul său nume;

Câmpurile înregistrării pot aparţine unortipuri de date diferite (de aceea spunemcă este o structură neomogenă);

În memorie câmpurile sunt aşezateconsecutiv (în linie), ocupând o zonă de memorie compactă.

Page 16: Programare Orientata Obiect Novac

16

Primele două caracteristici se referă la conceptul abstract de înregistrare, iarultima caracteristică se referă la modulde implementare.

Câmpurile de date dintr-o înregistare pot conţine nu numai date primitive, ci şistructuri de date.

În particular, orice câmp al unei înregis-trări poate fi el însuşi o înregistrare.

Page 17: Programare Orientata Obiect Novac

17

Clasa ca extindere a structuriide înregistrare În limbajele de programare OO, structura de

înregistrare a fost extinsă, astfel încât în afară de date sa conţină şi metode, adică funcţii sauproceduri prin care se prelucrează datele respective.

S-a obţinut astfel conceptul de clasă. Clasa nu mai este o simplă structură de date, ci un

modul de program, care conţine atât date, cât şimetode.

Se poate deci considera că înregistrarea este un cazparticular de clasă, care nu conţine metode.

Page 18: Programare Orientata Obiect Novac

18

Clasele – structuri abstracte de date, definite de utilizator, care “încapsulează” atât datele propriu-zise cât şi operaţiile efectuate asupra acestora.

Un obiect este o instanţă a unei clase. Clasa = abstractizare logică; Obiect = real, există în memoria

calculatorului; O clasă are atribute (caracteristici-date)

şi metode (funcţii);

Page 19: Programare Orientata Obiect Novac

19

Îmbunătăţiri ale limbajului C introduse în C++

1. Transmiterea parametrilorÎn C++ există 2 posibilităţi de transmitere a param. actuali către o funcţie: Prin valoare; Prin referinţă.

Primul este modul standard de transmitere a param. în C.

Page 20: Programare Orientata Obiect Novac

20

Transmiterea parametrilor prin referinţă

Prin folosirea param formali referinţă se permite realizarea transferului prin adresă, la fel ca în Pascal (paramerii VAR).

Se elimină astfel necesitatea utilizarii param formali pointeri, în cazul în care modificările făcute în interiorul funcţiei asupra param. trebuie să rămână şi după revenirea din procedură.

Page 21: Programare Orientata Obiect Novac

21

Exemplu

void schimbă(int &a, int &b){int aux=a; a=b; b=aux;} Transferul prin referinţă este util atunci

când programul are dimensiune mare (struct, class) şi crearea în stivă a unei copii a valorii lui reduce viteza de execuţie şi încarcă memoria.

Page 22: Programare Orientata Obiect Novac

22

2. Parametri cu valori implicite

În C++ se pot declara funcţii cu valori implicite ale parametrilor;

La apelarea acestor funcţii se poate omite specificarea param efectivi pentru aceia care au fost declaraţi cu valori implicite;

Este obligatoriu ca numai ultimii param să aibă valori implicite şi nu este permisă alternarea param cu şi fară valori implicite.

Page 23: Programare Orientata Obiect Novac

23

Exemplu- Val_impl.cpp

void fct(int, int=10);void fct(int p1, int p2){

cout<<p1; cout<<p2; }void main(){ fct(1,2);

fct(3);}

Page 24: Programare Orientata Obiect Novac

24

3. Funcţii inline

Prezenţa funcţiilor inline anunţă compila-torul să nu mai genereze cod maşină necesar apelului şi revenirii, ceea ce conduce la micşorarea duratei de execuţie.

Practic, funcţiile care au corpul format din maximum 3 instrucţiuni şi nu conţin instrucţiuni repetitive (for, while, do-while) pot fi declarate funcţii inline.

Page 25: Programare Orientata Obiect Novac

25

•Declararea funcţiei inline

inline <tip_vret><nume>(lista param. formali);

În cazul metodelor unei clase, dacă acestea sunt definite în interiorul clasei, ele sunt considerate implicit funcţii inline;

Există şi posibilitatea de a declara metoda la definirea clasei şi de a specifica, explicit, că este funcţie inline la definirea funcţiei.

Page 26: Programare Orientata Obiect Novac

26

Exempluclass Dreptunghi {//……….

public://….void seteaza_dim (double, double);

//declarare metoda};inline void Dreptunghi::seteaza_dim (double

L, double l){lung=L;lat=l;}

Page 27: Programare Orientata Obiect Novac

27

4. Supradefinirea (supraîncărcarea) funcţiilor

C++ permite supraîncărcarea (overloading) funcţiilor, adică existenţa mai multor funcţii cu acelaşi nume;

Compilatorul va determina care funcţie va fi apelată prin examinarea numărului şi tipului de argumente;

Nu se verifică şi tipul valorii returnate, deci 2 fct. supraîncărcate NU pot diferi doar prin valoarea returnată.

Page 28: Programare Orientata Obiect Novac

28

Exemplu

void fct(int a) {cout <<a<<”functia 1”;}void fct(char *a) {cout<<“\n”<<“a= “<<” functia 2”;}void main() {char a=‘A’;fct(3);fct(&a);}

Page 29: Programare Orientata Obiect Novac

29

5. Alocarea dinamică a memoriei folosind new şi delete

Operatorii new şi delete sunt similari fct. malloc() şi free(), dar constituie o metodă superioară adaptată POO;

Operatorul new poate fi folosit în următoarele situaţii:

int *ip1, *ip2,*ip3;ip1=new int; // var. intrega neinitializataip2=new(2); // var. int initializata cu 2ip3=new[100]; //tablou de 100 de intregi

Page 30: Programare Orientata Obiect Novac

30

Operatorii new şi delete

Operatorul new poate fi folosit şi la alocarea dinamică a obiectelor (apelarea constructorului clasei);

Operatorul delete este complementarul lui new şi permite eliberarea memoriei alocate (apelarea destructorului clasei).

Page 31: Programare Orientata Obiect Novac

31

6. Operatorul de rezoluţie

În C++ este definit un operator de rezoluţie ::, a cărui principală aplicaţie este legată de clase şi obiecte.

Exemplu:int n=1;void main() {int n=2; afiseaza(n); //afiseaza 2afiseaza(::n); // afiseaza 1}

Page 32: Programare Orientata Obiect Novac

CLASE ÎN C++

Page 33: Programare Orientata Obiect Novac

Tipul class

În C++ clasa este un concept fundamental prin care se definesc noi tipuri de date, prin asocierea unui set de funcţii la o structură de date;

Definirea unei clase presupune declararea ei prin specificarea numelui, lista claselor de bază din care este derivată clasa, dacă există, şi membrii clasei- atribute (date) şi metode (funcţii).

Page 34: Programare Orientata Obiect Novac

Definirea unei clase – antet şi corp Antetul este format din cuvântul cheie

class urmat de numele clasei. Corpul clasei este cuprins între {} şi

conţine membrii clasei, urmaţi de ; sau de o listă de declarare.

Exemplu: class Screen { /* ... */ };class Screen { /* ... */ } ecranA, ecranB;

Datele membre se declară exact ca variabilele C obişnuite, exceptând faptul cănu pot fi iniţializate explicit.

Page 35: Programare Orientata Obiect Novac

Exemplu

class Screen { short row, col; // nr linii şi coloanechar *cursor; // poziţia curentă a cursoruluichar *screen; // matricea ecran, row*col

};

Page 36: Programare Orientata Obiect Novac

Observaţii

Este bine ca datele membre să se specificeîn ordinea crescătoare a dimensiunii, acestfapt putând asigura o alocare optimă pe toatemaşinile.

Un obiect al unei clase poate fi declaratmembru doar dacă clasa a fost deja definită.

Definirea se încheie în momentul apariţiei }. Nu se pot declara membri de tipul clasei.

Page 37: Programare Orientata Obiect Novac

Declararea claselor

class nume_tip { modificator_control_acces:

lista_membrilor;} lista_variabile; Clasa reprezintă un tip de date definit de utilizator; Membrii unei clase sunt:- Atribute – datele declarate în cadrul clasei;- Metode – funcţii membre declarate sau definite în

clasă.

Page 38: Programare Orientata Obiect Novac

Modificator control accesclass <nume clasa>{private:

//zona privată- numai a clasei respective; de regulă cuvântul private poate lipsiprotected:

//zona (optională) accesibilă clasei şi descendenţilor ei;

public://interfaţa cu lumea exterioară clasei};

Page 39: Programare Orientata Obiect Novac

Exemplul 1: class dreptunghiclass dreptunghi {

double Lung, lat;public:void seteaza-dimen(double, double);double arata_Lung() {return Lung;}double arata_lat() {return lat;}double calcul_arie() {return Lung*lat;}

};

Page 40: Programare Orientata Obiect Novac

Membrii statici ai unei clase Fiecare obiect are propriile lui copii ale tuturor membrilor

acelei clase. Este posibila definirea de membrii care sa fie folositi în

comun de catre toate obiectele clasei. Datele statice exista într-o singura copie, comuna tuturor

obiectelor. Crearea, initializarea si accesul la aceste date statice

sunt total independente de obiectele clasei. Functiile membre statice efectueaza operatii care sunt

asociate întregii clase. Din acest motiv, la apelarea lornu este obligatorie indicarea unui obiect.

Page 41: Programare Orientata Obiect Novac

Exemplul 2:class masina{char *culoare;//membru implicit private

int capacit_cil; // membru private

public:void citire_date();int ret_capacit();

}; culoare si capacit_cil pot fi accesati numai

prin metodele clasei.

Page 42: Programare Orientata Obiect Novac

Exemplul 3

class Persoana{char *nume; // data privata

public:void citire_inf(); // metoda publica

private:int varsta; //data privata

};

Page 43: Programare Orientata Obiect Novac

Pointerul this

Fiecare funcţie membră are un argument ascuns numit this, transmis automat de către compilator.

Această variabilă (locală) reprezintă pointerul către obiectul curent (cel care apeleză metoda).

Să implementăm metoda calcul_ariefolosind acest pointer.

Page 44: Programare Orientata Obiect Novac

Exemplu pentru thisclass Dreptunghi{

double lung, lat;public:

//……………………void seteaza_dimen(double,double);

};void Dreptunghi::seteaza_dimen(double L, double

l){this->lung=L;this->lat=l;}

Page 45: Programare Orientata Obiect Novac

Obiecte Un obiect este o instanţă a unei clase;

Exemplu: dreptunghi a; Se pot declara oricate obiecte ale unei clase; Declararea obiectelor are o formă

asemănătoare declarării datelor de tip predefinit:

nume_clasa lista_obiecte;Exemplu: dreptunghi a,b,c;Dreptunghi.cpp

Page 46: Programare Orientata Obiect Novac

Domeniul unui numeVizibilitateTimp de viaţă

Page 47: Programare Orientata Obiect Novac

Domeniul unui nume Unui nume îi corepunde un domeniu,

specificat prin declaraţia variabilei; În funcţie de poziţia definirii unui nume,

domeniul poate fi: local (dacă numele este declarat într-un bloc; fişier (dacă numele este declarat în afara oricărui

bloc sau declaraţie de clasă); clasă;

Dacă un nume care are ca domeniu un fişier este redefinit într-un bloc inclus în domeniul său, el poate fi folosit în acel bloc dacă este precedat de operatorul de rezoluţie (::);

Page 48: Programare Orientata Obiect Novac

Exemplu#include <iostream.h>int i=89; // i declarat in afara oricarei func.,

// domeniul numelui este fisierulvoid main(){double i=99.9;cout<<“Valoarea lui i=“<<i<<‘\n’; // i=89cout<<“Valoarea lui i=“<<::i<<‘\n’; // i=99.9}

Page 49: Programare Orientata Obiect Novac

Domeniul numelui unui tip de date definit într-o clasă Se stabileşte în mod similar domeniului

oricărei variabile; Numele unui membru al unei clase are

un domeniu de tip clasă; Ca orice nume, un nume de clasă poate

fi redeclarat;

Page 50: Programare Orientata Obiect Novac

Exempluclass a {//………};//…..{ //instructiune bloc aflata in domeniul

numelui adouble a=99; //redeclararea lui aclass::a x; // x este un obiect de tipul a (al

clasei a)}

Page 51: Programare Orientata Obiect Novac

Vizibilitate

Domeniul de vizibilitate al unei variabile (obiect) este determinat de clasa de memorare a varibilei (obiectului)

De obicei domeniul de vizibilitate al unui nume coincide cu domeniul numelui.

Page 52: Programare Orientata Obiect Novac

Variabile locale şi variabile globaleDefiniţiiVaribilele declarate în afara oricărei funcţii

sunt variabile globale; Variabilele declarate în interiorul unui bloc

sunt variabile locale;Porţiunea de cod în care o variabilă este

accesibilă reprezintă scopul (domeniul de vizibilitate ) al variabilei respective;

Parametrii formali ai unei funcţii sunt variabile locale ale funcţiei respective;

Page 53: Programare Orientata Obiect Novac

Timpul de viaţă

Timpul de viaţă al unei variabile locale este durata de execuţie a blocului (funcţiei) în care a fost definită;

Timpul de viaţă al unei variabile globale este durata de execuţie a programului.

Page 54: Programare Orientata Obiect Novac

Exempluint x; //variabila globala, vizibila in tot

// programulvoid main(){ int a,b; // variabile locale main()//…….}int y; // variabila externa vizibila din acest

// punct si pana la sf. fisierului sursavoid func1(void){ int c,d; // variabile locale in func1//……..}

Page 55: Programare Orientata Obiect Novac

Clase de memorare Clasa de memorare determină timpul

de viaţă şi domeniul de vizibilitate al unei variabile

Se specifică la declararea variabilei, prin unul dintre cuvintele cheie:auto auto int a;register register char c;extern extern double z;static static int x;

Page 56: Programare Orientata Obiect Novac

Clasa de memorare auto Este clasa de memorare implicită

pentru o variabilă locală dacă nu se declară nimic;

Se alocă memorie automat la intrarea în blocul sau în funcţia în care este declarată.

Domeniul de vizibilitate este blocul sau funcţia unde a fost declarată;

Timpul de viaţă este durata de execuţie a blocului sau funcţiei respective.

Page 57: Programare Orientata Obiect Novac

Clasa de memorare register Variabilele din această clasă au aceeaşi

vizibilitate şi timp de viaţă ca şi cele din clasa auto;

Diferenţa constă în faptul că pentruvariabile register compilatorul utilizează regiştrii interni;

Unei variabile register nu i se poate aplica operatorul de referenţiere (::);

Page 58: Programare Orientata Obiect Novac

Clasa de memorare extern O varibilă globală are implicit clasa

extern, dacă nu există altă declaraţie; Domeniul de vizibilitate este din locul

declarării până la sfârşitul fişierului sursă;

Timpul de viaţă este durata execuţiei programului;

O variabilă din clasa extern este automat iniţializată la 0.

Page 59: Programare Orientata Obiect Novac

Clasa de memorare staticAre două utilizări distincte: Variabile locale statice – Dv = blocul

sau funcţia unde sunt definite; Tv=durata de execuţie a programului. Se iniţializează automat la 0.

Variabile globale statice – Dv = locul în care au fost definite şi până la sfârşitul fişierului; Tv = durata execuţiei programului.

Page 60: Programare Orientata Obiect Novac

1

CONSTRUCTORI ŞI DESTRUCTORI

Page 61: Programare Orientata Obiect Novac

2

În C++ se folosesc funcţii membre numite constructori şi destructori pentru crearea, iniţializarea, copierea şi distrugerea obiectelor. Constructorii şi destructorii sunt funcţii membre ale unei clase.

Un constructor – este o funcţie specială membră a unei clase şi are acelaşi nume cu acea clasă;

Are rolul de a iniţializa obiectele (instanţele acelei clase) atunci când sunt create.

Page 62: Programare Orientata Obiect Novac

3

Constructori şi destructoriconstr_destr.cpp Complementul constructorului este

destructorul- distruge obiectele create; Destructorul are acelaşi nume cu

constructorul, dar precedat de caracterul ~.

Obiectele locale sunt create când se intră în blocul lor şi distruse când se termină programul.

Page 63: Programare Orientata Obiect Novac

4

#include <iostream.h>int n_obiecte=0;class OB{public:

OB(){n_obiecte++;cout<<"Numarul obiectelor in viata

"<<n_obiecte<<endl;}~OB(){n_obiecte--;cout<<"Au mai ramas doar "<<n_obiecte<<" obiecte

"<<endl;}

};

Page 64: Programare Orientata Obiect Novac

5

void main(){OB a,b,c; //creez primele 3 obiecte{OB d,e;

} // aici distrug d si e{ // redeschid alt contextOB f; //crez un nou obiect f

} // distrug f} // eliberez memoria ocupata de obiectele a,b,c

Page 65: Programare Orientata Obiect Novac

6

Particularităţi specifice constructorilor Numele coincide cu numele clasei

căreia îi aparţine; În declaraţii nu se specifică nici un tip

de rezultat; Pot fi mai mulţi constructori pentru

aceeaşi clasă, deosebirea realizându-se prin mecanisme de overloading;

Page 66: Programare Orientata Obiect Novac

7

Particularităţi specifice constructorilor Pot avea parametri, inclusiv parametri

impliciţi; Un constructor nu poate fi apelatexplicit într-

un program, ci este apelat automat la crearea obiectului din clasa respectivă (static, auto, dinamic) inclusiv pentru obiecte temporare (în cazul alocării dinamice se foloseşte operatorul new);

Page 67: Programare Orientata Obiect Novac

8

Particularităţi specifice constructorilor

Nu se pot utiliza pointeri către constructori; Nu pot fi moşteniţi dar pot fi apelaţi de clasa

derivată; Dacă un constructor nu are parametri =

constructor cu lista vidă; Dacă o clasă nu dispune explicit de constructori

definiţi, complilatorul acţioneză automat un constructor ca funcţie membră publică, fiind în acelaşi timp constructor cu listă şi corp, ambelevide;

Page 68: Programare Orientata Obiect Novac

9

Particularităţi specifice constructorilor O clasă cu constructor private nu

poate avea obiecte. Ea poate fi doar baza unei ierarhii de clase.

Page 69: Programare Orientata Obiect Novac

10

Tipuri de constructori Există 3 tipuri de constructori care diferă prin

lista de aparametri:1. Constructor de copiere pentru construcţii de

forma adr1=ad2. Forma acestui constr. este<nume_clasa>(<nume_clasa>&);

2. Constructor cu listă şi corp vide, echivalent cu constructorul implicit;

3. Constructor de iniţializare. Nu are ca parametru un obiect deoarece se ocupă de iniţializarea obiectelor ce se vor construi. Nu trebuie să existe neaparat identitate între nr. de param. şi nr. de câmpuri. Se pot folosi şi parametri impliciţi.

Page 70: Programare Orientata Obiect Novac

11

Scopul folosirii constructorilor Asigură iniţializarea corectă a

obiectelor dintr-o clasă; Asigură unicitatea iniţializării; Au rolul construirii obiectelor, deci a

alocării memoriei; Sunt importanţi atât pentru obiecte

statice cât şi pentru obiecte din memoria dinamică.

Page 71: Programare Orientata Obiect Novac

12

Exemplu pentru cele 3 tipuri de constructori –Pers.cpp#include<conio.h>#include<iostream.h>#include<string.h>#define MAX 20class Adresa{char

nume[MAX],prenume[MAX],strada[MAX];int numar;

Page 72: Programare Orientata Obiect Novac

13

public:Adresa() {}; //constr. explicit cu lista si corp//Adresa(Adresa&); //constr. de copiereAdresa(char*, char*, char*, int);//contr.init.void tip_adresa();//metoda de afisare

};

Page 73: Programare Orientata Obiect Novac

14

Adresa::Adresa(char cnume[],char cprenume[], char cstrada[],int inumar)

{ strcpy(nume,cnume);strcpy(prenume,cprenume);strcpy(strada,cstrada);numar=inumar;

}void Adresa::tip_adresa(){ cout<<nume<<" "<<prenume<<"

"<<"str."<<strada<<" nr."<<numar<<'\n';}

Page 74: Programare Orientata Obiect Novac

15

void main(){ Adresa

adr1("Popescu","Ion","Domneasca", 21);Adresa adr2;

adr1.tip_adresa();adr2=adr1;adr2.tip_adresa();getch();}

Page 75: Programare Orientata Obiect Novac

16

Particularităţi specifice destructorilor Numele destructorilor este format din

caracterul ~ şi numele clasei căreia îi aparţine;

În declaraţii nu se specifică nici un tip de rezultat;

Nu are parametri şi nu poate fi supradefinit sau solicitat prin program pentru obiecte dinamice cu operatori anume, inclusiv pentru variabile temporale;

Page 76: Programare Orientata Obiect Novac

17

Particularităţi specifice destructorilor Nu se pot utiliza pointeri către

destructori; Nu pot fi moşteniţi dar pot fi apelaţi de

clasa derivată; Dacă o clasă nu dispune explicit de un

destructor, compilatorul generează un destructor implicit public cu corp vid;

Page 77: Programare Orientata Obiect Novac

18

Particularităţi specifice destructorilor Se apelează implicit pentru obiecte

alocate în memoria statică la sfârşitul execuţiei programului; - pentru obiectele de pe stivă-în momentul

ieşirii din blocul în care au fost definite; - pentru obiecte alocate dinamic cu new, la

apelarea dealocării cu delete.

Page 78: Programare Orientata Obiect Novac

19

Ordinea executării operaţiilor la apelarea constructorilor şi destructorilor1. Pentru constructori: - se alocă spaţiu îm memorie pentru

obiectul respectiv; - se execută instrucţiunile din

constructor, dacă există.

Page 79: Programare Orientata Obiect Novac

20

Ordinea executării operaţiilor la apelarea constructorilor şi destructorilor2. Pentru destructori: - se execută instrucţiunile din corpul

destructorilor, dacă există; - se distruge obiectul eliberând spaţiul de

memorie.Obsevaţie: Ordinea de apelare implicită pentru

destructorii unor obiecte este inversă ordinii în care au fost construite obiectele în blocul respectiv.

Page 80: Programare Orientata Obiect Novac

1

Clasa COMPLEX Să se definească tipul abstract de date

Complex care să aibă funcţii membru:ModulArgumentAccesul la partea realăAccesul la partea imaginarăAfişarea unui număr complex;şi constructori pentru iniţializare şi copiere.

Page 81: Programare Orientata Obiect Novac

2

Fişierul ClsCOMPLEX.hclass Complex {double real;double imag;public:Complex(double x=0,double y=0); //constructor de initializareComplex(const Complex&); //constructor de copiere

double modul(); //modulul nr complexdouble arg(); // argument nr complexdouble retreal(); // returneaza partea reala a nr. complexdouble retimag(); // returneaza partea imag a nr. complexvoid afiscomplex();void suma(Complex *,Complex *);

};

Page 82: Programare Orientata Obiect Novac

3

Fcmembre.cpp#include <math.h>#include <iostream.h>#define PI 3.14159#include "ClsCOMPLEX.h"//Constructor pentru initializareinline Complex::Complex(double x, double y){real=x;imag-y;

}// Constructor de copiereinline Complex::Complex(const Complex& z){real=z.real;imag=z.imag;

}// Calculeaza modulul nr complexinline double Complex::modul(){return sqrt(real*real+imag*imag);

}

Page 83: Programare Orientata Obiect Novac

4

// Calculeaza argumentuldouble Complex:: arg(){double a;if(real==0 && imag==0)a=0.0;if(real!=0 && imag!=0)a=atan(imag/real);if(real==0 && imag>0)a=PI/2;if(real==0&&imag<0)a=3*PI/2;

return a;}// Returneaza partea realainline double Complex::retreal(){ return real;}// Returneaza partea imaginarainline double Complex::retimag(){ return imag;}//Afiseaza numar complexinline void Complex::afiscomplex(){cout<<real<<"+"<<imag<<" i"<<'\n';}

Page 84: Programare Orientata Obiect Novac

5

Complexe.cpp- program care realizează următoarele: Citeşte perechi de numere care reprezintă

partea reală şi respectiv imaginară a unui număr complex;

Afişează: - Numărul complex citit; - Modulul fiecărui număr complex citit; - Suma numerelor complexe citite.

Page 85: Programare Orientata Obiect Novac

6

void main(){float re;float im;cout<<"Partea reala ";cin>>re;cout<<"Partea imaginara ";cin>>im;Complex z1(re,im),z2(5,8),z3;cout<<"Primul numar complex"<<'\n';z1.afiscomplex();cout<<"Modulul= "<<z1.modul()<<'\n';cout<<"Argumentul= "<<z1.arg()<<'\n';cout<<"Al doilea numar complex"<<'\n';z2.afiscomplex();z3.suma(&z1,&z2);cout<<"Suma numerelor complexe este "<<'\n';z3.afiscomplex();}

Page 86: Programare Orientata Obiect Novac

7

Funcţii friend

Se poate permite unei funcţii care nu este membră să aibă acces la membrii private şi protected ai clasei căreia îi este prietenă (friend).

Pentru a declara o funcţie friend se include prototipul ei în acea clasă, precedat de cuvântul cheie friend.

Page 87: Programare Orientata Obiect Novac

8

Spre deosebire de funcţiile membre funcţiile friend nu posedă pointerul this implicit.

Acest lucru conduce la faptul că o funcţie friend are un parametru în plus faţă de o funcţie membru care are acelaşi efect.

O funcţie poate fi în acelaşi timp funcţie membră a unei clase şi prietenă a altei clase.

Page 88: Programare Orientata Obiect Novac

9

Exempluclass CLS1 {int f1(int, char); // f1 metoda a clasei CLS1//…

};class CLS2 {friend int CLS1::f1(int, char); // f1 – friend

// clasa CLS2};

Page 89: Programare Orientata Obiect Novac

10

În cazul în care se doreşte ca toatefuncţiile membre ale unei clase să aibăacces la membrii privaţi ai altei clase (să fie funcţii prietene), prima clasă poate fi declarată clasă prietenă pentru cea de-a doua.

Page 90: Programare Orientata Obiect Novac

11

Exempluclass CLS1;class CLS2 { //….friend CLS1; // CLS1 este clasa prietena

CLS2// …

};

Page 91: Programare Orientata Obiect Novac

12

Relaţia de clasă prietenă nu estetranzitivă.

Astfel, dacă clasa CLS1 este clasă prietenă a clasei CLS2, iar clasa CLS2 este clasă prietenă clasei CLS3, aceasta NU implică faptul că CLS1 este clasă prietenă pentru CLS3.

Page 92: Programare Orientata Obiect Novac

13

Modificatorii de protecţie nu au nici o influenţă asupra unei funcţii prietene;

De aceea, specificarea faptului că o funcţie este prieten pentru o clasă poate fi scrisă în orice punct din interiorul definiţiei clasei respective.

Funcţia prieten nu este protejată şi deci poate fi utilizată fără nici o restricţie, ca o funcţie obişnuită.

Page 93: Programare Orientata Obiect Novac

14

Să se scrie o funcţie care ridică un număr complex la o putere întreagă pozitivă.

Formula lui Moivre:(r*(cos(a)+isin(a)))**n=r**n(cos(n*a)+isin(n*a)unde:a=argumentul numarului complex;r=modulul nr. complex.

Page 94: Programare Orientata Obiect Novac

15

Funcţia cputerevoid cputere(Complex& z,int n){ double r,a;r=z.modul();a=z.arg();double rlan=pow(r,(double)n);double na=n*a;z.real=rlan*cos(na);z.imag=rlan*sin(na);}

Page 95: Programare Orientata Obiect Novac

16

Observaţie

Funcţia cputere nu este o funcţie membră a clasei Complex;

Ea are acces la atributele real şi imag ale obiectului de tip complex referit de z, numai dacă este o funcţie prietenă a clasei Complex.

Page 96: Programare Orientata Obiect Novac

1

Moştenirea-ierarhii de clase în C++

Page 97: Programare Orientata Obiect Novac

2

Mecanismul moştenirii

Caracteristică a limbajelor POO, care permite refolosirea şi extinderea funcţionalităţii claselor existente;

Permite crearea unei ierarhii de clase şi trecerea de la clase generale la clase particulare;

Procesul implică la început definirea clasei de bază, care stabileşte proprietăţile comune.

Page 98: Programare Orientata Obiect Novac

3

Moştenirea poate fi:

Unică- o clasa are doar o superclasă, rezultând o structură arborescentă;

Multiplă – o clasă are mai multe superclase, rezultând o structură de reţea.

Înformaţia comună apare în clasa de bază, iar informaţia specifică, în clasa derivată.

Page 99: Programare Orientata Obiect Novac

4

Page 100: Programare Orientata Obiect Novac

5

Clasa derivată reprezintă o specializare a clasei de bază;

Orice clasă derivată moşteneşte datele membre şi metodele clasei de bază;

Acestea nu trebuie redeclarate în clasa derivată.

Page 101: Programare Orientata Obiect Novac

6

Nivelul de acces la membrii unei clase private – membrii (date şi metode) pot

fi accesaţi doar prin metodele clasei; protected – membrii pot fi accesaţi prin

funcţiile membre ale clasei şi funcţiile membre ale clasei derivate;

public – membrii pot fi accesaţi din orice punct al domeniului de existenţă al clasei respective;

friend – membrii pot fi accesaţi prin funcţiile membre ale funcţiei prietene specificate.

Page 102: Programare Orientata Obiect Novac

7

Tipul de moştenire Publică – în clasa derivată, nivelul de acces

al membrilor este acelaşi ca în clasa de bază. Privată – membrii protected şi public din

clasa de bază devin private în clasa derivată. Protejată (compilatoare mai noi)– la fel ca în

moştenirea privată, dar membrii publici ai clasei de bază devin protejaţi în timpul derivărilor ulterioare.

Page 103: Programare Orientata Obiect Novac

8

Page 104: Programare Orientata Obiect Novac

9

Clase derivate

O clasă derivată include toate caracteristicile clasei de bază şi în plus atribute proprii;

La declarare se specifică o listă a claselor de bază, precedate de modificatorul de acces care precizează tipul moştenirii.

Page 105: Programare Orientata Obiect Novac

10

Forma generală a moştenirii

class <nume_clasa_deriv>:<acces> <clasa_baza>{// corpul noii clase};<acces>:private, protected, public Obsevaţii:

O clasă derivată are acces atât la proprii membri cât şi la membrii publici ai clasei de bază.

Page 106: Programare Orientata Obiect Novac

11

Exemplu:

class Cladire{ //clasa derivata din cladireint camere, etaje, supraf; class Casa : public Cladire {public: int dormitoare, bai;void nr_camere (int num); public :int cate_camere(); void nr_dormitoare(int num); void nr_etaje (int num); int cate_dormitoare ();int cate_etaje (); void nr_bai (int num);void nr_supraf (int num); int cate_bai ();int cate_supraf(); };

};

Page 107: Programare Orientata Obiect Novac

12

Declararea clasei derivate Angajat, clasa de bază Persoana (moştenire simplă)

class Persoana{// corpul clasei

};class Angajat:protected Persoana{double salariu;

};

Page 108: Programare Orientata Obiect Novac

13

Declararea clasei derivate Interfaţa, cu clasele de baza Fereastra şi MeniuMoştenire multiplă

class Fereastra {// membrii clasei};class Meniu {//membrii clasei};class Interfata:public Fereastra, public Meniu{//membrii clasei};

Page 109: Programare Orientata Obiect Novac

14

Compilarea şi editarea de legături

Clasa derivată şi clasa de bază pot fi declarate în acelaşi fişier sursă sau în fişiere diferite.

Page 110: Programare Orientata Obiect Novac

15

Constructorii claselor derivate

Constructorii şi destructorii sunt funcţii membre care nu se moştenesc.

La instanţierea unui obiect din clasa derivată se apelează mai întâi constructorii claselor de bază, în ordinea în care aceştia apar în lista din declararea clasei derivate.

Page 111: Programare Orientata Obiect Novac

16

La distrugerea obiectelor, se apelează prima dată destructorul clasei derivate, apoi destructorii claselor de bază.

Transmiterea argumentelor unei funcţii constructor din clasa de bază se face folosind o formă extinsă a declaraţiei constructo-rului clasei derivate, care transmite argumentul unuia sau mai multor constructori din clasa de bază.

Page 112: Programare Orientata Obiect Novac

17

Concluzii

În general, clasele utilizează constructori definiţi de programator;

Dacă aceştia lipsesc, compilatorul generează automat un constructor implicit pentru clasa respectivă;

Page 113: Programare Orientata Obiect Novac

18

La instanţierea unui obiect o parte din valorile primite ca parametrifolosesc la iniţializarea datelor membre ale clasei de bază, iar restul iniţializează datele clasei derivate.

Page 114: Programare Orientata Obiect Novac

1

Relaţia dintre constructorii şi destructorii claselor de bază şi ai clasei derivate

Moştenire în C++

Page 115: Programare Orientata Obiect Novac

2

Constructorii şi destructorii sunt funcţii membru care nu se moştenesc;La instanţierea unui obiect al unei

clase derivate se apelează atât constructorii clasei derivate cât şi cei ai claselor de bază;La început, se apeleză constructorii

claselor de bază şi apoi construc-torul clasei derivate;

Page 116: Programare Orientata Obiect Novac

3

Ordinea de apel a constructorilor corespunde cu ordinea în care sunt indicate clasele respective în lista_claselor_de bază din definiţia clasei derivate;

La distrugerea unui obiect al clasei derivate, destructorii se apeleză în ordinea inversă;

Deci, întâi se apeleză destructorul clasei derivate şi apoi se apleleză destructorii claselor de bază în ordinea inversă faţă de ordinea de apel a constructorilor la instanţierea obiectului respectiv;

Page 117: Programare Orientata Obiect Novac

4

La instanţierea unui obiect se trans-mit valori parametrilor constructo-rilor pentru iniţializarea datelor membru; În cazul unui obiect al unei clase

derivate, o parte din valori se folosesc pentru iniţializarea datelor membru specifice ale clasei deriva-te, iar restul pentru iniţializarea datelor membru ale claselor de bază;

Page 118: Programare Orientata Obiect Novac

5

Constructorul clasei derivate conţi-ne parametri pentru toate valorile care se utilizează la iniţializarea obiectelor;Transferul valorilor de iniţializare

pentru datele membru ale claselor de bază se defineşte cu ajutorul antetului constructorului clasei derivate;

Page 119: Programare Orientata Obiect Novac

6

Fie A o clasă derivată din clasele de bază B1, B2,...,Bn:

class A:public B1,public B2,...,public Bn{…

A(…); // prototip pentru constructor…};

Constructorul A are un antet de forma:A::A(…):B1(…),B2(…),…,Bn(…)

Page 120: Programare Orientata Obiect Novac

7

Constructorul A are o listă de parametri completă, adică pentru iniţializarea tuturor datelor membru ale unui obiect de tip A;

Expresia Bi(...) (i=1,2,..,n) din antetulconstructorului A conţine, în paranteză, o listă de expresii care definesc valori iniţiale pentru datele membru ale clasei Bi.

Dacă o clasă Bi nu are constructor, atunci pentru clasa respectivă nu va fi prezentă o expresie de forma Bi(...) în antetul constructorului A.

Page 121: Programare Orientata Obiect Novac

8

De asemenea, expresia respectivă nu va fi prezentă în antetul lui A dacă datele membru ale clasei Bi se iniţializează cu valori implicite sau clasa Bi nu are date membru;

Expresia Bi(...) este un apel explicit al uni constructor al clasei Bi.

Ordinea în care se scriu expresiile Bi(...) în antetul constructorului A este arbitrară;

Constructorii se apeleză întotdeauna în ordinea în care sunt scrise clasele în lista_claselor_de_bază.

Page 122: Programare Orientata Obiect Novac

9

O condiţie esenţială pentru a se putea apela constructorii claselor de bază prin intermediul clasei derivate este ca aceştia să aibă protecţia de tip protected sau public.Lista care defineşte apelurile

constructorilor claselor de bază nu este prezentă în prototipurile constructorilor claselor derivate ci numai în antetele acestora.

Page 123: Programare Orientata Obiect Novac

10

În general, clasele au constructori definiţi de programatori;Totuşi există situaţii în care o clasă

nu are constructori definiţi; În acest caz, complilatorul

generează în mod automat un constructor implicit (fară parametri) pentru clasa respectivă.

Page 124: Programare Orientata Obiect Novac

11

Exemple1. Clasa A este o clasă derivată din

clasa de bază B. Nici una din clase nu are un constructor,Fie instanţierea:A a;Obiectul a se instanţiază fară a se face iniţializări. La instanţiere se aplică constructorii impliciţi ai claselor, generaţi de compilator.

Page 125: Programare Orientata Obiect Novac

12

Exemplul 2

Clasa A este o clasă derivată a clasei de bază B;Clasa B are constructor cu toţi

parametri impliciţi:class B {

protected:double x,y;

Page 126: Programare Orientata Obiect Novac

13

public:B(double p=0,double q=0){x=p;y=q;

}…

}; Clasa A nu are constructor:

Page 127: Programare Orientata Obiect Novac

14

class A:public B{protected:

Boolean ecran;public:

interior();…

};Fie declaraţia:

A a;

Page 128: Programare Orientata Obiect Novac

15

Obiectul a se instanţiază apelându-se constructorul cu parametri impliciţi al clasei B.Datele membru x şi z se iniţializea-

ză cu valoarea 0, iar data membru ecran nu este iniţializată.

Page 129: Programare Orientata Obiect Novac

16

Exemplul 3Clasa A este o clasă derivată a

clasei B. Clasa B nu are constructor definit.class B {protected:

double x,y;public:…. // nu exista constructori

};

Page 130: Programare Orientata Obiect Novac

17

Clasa A nu are constructor:class A:public B {

protected :Boolean ecran;int abs,ord;

public:A(double p=0,double q=0,int lx=639,int ly=349)

{ // initializeaza datele membru ale clasei de baza

x=p; y=q;

Page 131: Programare Orientata Obiect Novac

18

// initializeaza datele membru specificeabs=lx;ord=ly;if(0<=p && p<=lx && 0<=q && q<=ly)

ecran=true;else

ecran=false;}

…};

Page 132: Programare Orientata Obiect Novac

19

Exemple de instanţieri

A a; /* a.x=0, a.y=0, a.abs=639, a.ord=349, a.ecran=true */

A b(100,400); /* b.x=100, b.y=400,b.abs=639, b.ord=349, b.ecran=false */

Page 133: Programare Orientata Obiect Novac

20

Exemplul 4 Clasa A este o clasă derivată a clasei B

şi ambele clase au constructori definiţi.class B {

protected:double x,y;

public:B(double xx=0,double yy=0){ x=xx; y=yy;}

…};

Page 134: Programare Orientata Obiect Novac

21

class A:public B {protected:

Boolean ecran;int abs,ord;

public:A(double p=0,double q=0,int lx=639, int ly=349):B(p,q){

abs=lx;ord=ly;

Page 135: Programare Orientata Obiect Novac

22

if(0<=p && p<=lx && 0<=q && q<=ly)ecran=true;

elseecran=false;

}…

};Se pot utiliza aceleaşi instanţieri ca

în exemplul 3.Se realizează aceleaşi instanţieri ca

în exemplul 3.

Page 136: Programare Orientata Obiect Novac

23

Observaţie:Datele abs şi ord pot fi instanţiate chiar în antetul constructorului ca mai jos:

A(double p=0,double q=0, int lx=639,int ly=349):B(p,q),abs(lx),ord(ly)

{if(0<=p && p<=lx && 0<=q &&q<=ly)

ecran=true;else

ecran=false;}…};

Page 137: Programare Orientata Obiect Novac

24

Observaţii O clasă derivată este necesar să aibă cel puţin

un constructor în cazul în care cel puţin o clasă de bază are un constructor care nu este implicit sau nu are toţi parametrii impliciţi;

Exemplele 1- 4 au fost analizate avându-se în vedere constructori obişnuiţi (nu de copiere !).

În lipsa constructorilor de copiere, compila-torul generează în mod automat constructori impliciţi, care, copiază datele membru ale obiectului sursă în datele membru ale obiectului destinaţie.

O copiere de acest tip se numeşte copiere bit cu bit.

Page 138: Programare Orientata Obiect Novac

25

Constructorii de copiere sunt necesari mai ales în cazul în care clasele au ca date membru pointeri spre zonele alocate dinamic în memoria heap;De asemenea, în condiţiile moşteni-

rii unor date membru ale claselor de bază, pot apărea situaţii în care copierea bit cu bit ar genera erori.

Page 139: Programare Orientata Obiect Novac

Supraîncărcarea operatorilor

SupraSupraîîncărcarea ncărcarea operatorilor operatorilor

îîn Cn C++++

Page 140: Programare Orientata Obiect Novac

2

• În C++ tipurile abstracte de date sedefinesc cu ajutorul claselor, dar nu se comportă la fel ca tipurile predefinite;

• Totuşi, există o serie de asemănări:– Datele de tip abstract (obiectele) se declară la

fel ca cele de tip predefinit;– De asemenea, ele pot fi iniţializate la

declarare.• În cazul tipurilor abstracte, operaţiile se

definesc cu ajutorul funcţiilor membre şi funcţiilor friend.

Page 141: Programare Orientata Obiect Novac

3

Exemplu

• Pentru clasa COMPLEX se pot definifuncţii membru şi funcţii friend pentru a realiza cele 4 operaţii aritmetice asupra obiectelor de tip COMPLEX.

• În definiţia de clasă de mai jos se foloseşte o funcţie membru şi una friend pentru adunarea, respectiv scăderea obiectelor de tip COMPLEX.

Page 142: Programare Orientata Obiect Novac

4

class COMPLEX {double real,imag;

public:COMPLEX(double x=0,double y=0) //constructor de

initializare{

real=x;imag=y;

}//functie membru pentru adunarea obiectelor de tip complex

COMPLEX adcomplex(COMPLEX& z2);//Functie friend pentru scaderefriend COMPLEX sccomplex(COMPLEX&, COMPLEX& );...

};

Page 143: Programare Orientata Obiect Novac

5

• În continuare se pot defini funcţiile adcomplex şi sccomplex ca mai jos:

COMPLEX COMPLEX::adcomplex(COMPLEX& z)//returneaza suma dintre obiectul curent// si cel transmis prin parametrul z{COMPLEX ztemp;ztemp.real=real+z.real;ztemp.imag=imag+z.imag;return ztemp;}

Page 144: Programare Orientata Obiect Novac

6

COMPLEX sccomplex(COMPLEX& z1,COMPLEX& z2)//returneaza diferenta z1-z2{

COMPLEX ztemp;ztemp.real=z1.real-z2.real;ztemp.imag=z1.imag-z2.imag;return ztemp;

}• Dacă a,b,c sunt 3 obiecte de tip Complex instanţiate

cu ajutorul declaraţiei:Complex a,b,c;

atunci instrucţiunea c=a.adcomplex(b);atribuie lui c de tip Complex rezultatul sumeiobiectelor complexe a şi b.

Page 145: Programare Orientata Obiect Novac

7

• De menţionat că apelul a.adcomplex(b) returnează un obiect de tip Complex la fel cum o funcţie de antet

tip nume_f(...)unde tip este un tip predefinit diferit de void

returnează o valoare de tip tip.În general dacă ob1 şi ob2 sunt obiecte din clasa CLASA:

CLASA ob1,ob2;atunci o expresie de forma ob1=ob2 esteadmisă de complilator şi ea atribuie lui ob1 valoarea obiectului ob2.

Page 146: Programare Orientata Obiect Novac

8

• Această atribuire se realizează prin copiere bit cu bit a valorilor componentelor lui ob2 în zonele de memorie alocate componentelor lui ob1.

• Cu toate acestea, tipul COMPLEX definit nu permite utilizarea operatorilor obişnuiţi pentru a exprima operaţii cu obiecte de tip COMPLEX ca în cazul operaţiilor cu numere de tip int, long, float sau double.

Page 147: Programare Orientata Obiect Novac

9

• Acest lucru este posibil prin mecamismul de supraîncărcare a operatorilor.

• Operatorii +şi – trebuie supraîncărcaţi pentru a realiza operaţii corespunzătoare cu obiecte de tip COMPLEX.

Page 148: Programare Orientata Obiect Novac

10

• Ca rezultat al supraîncărcării se ajunge ca operatorii respectivi să poată fi utilizaţi în expresii obişnuite cu operanzi obiecte de tipuri abstracte.

• Limbajul C++ permite supraîncărcarea numai a operatorilor existenţi în limbaj cu excepţia operatorilor:. :: ? :

Page 149: Programare Orientata Obiect Novac

11

• De asemenea, prin supraîncăr-care nu se poate schimba n-aritatea (unar sau binar), priori-tatea sau asociativitatea opera-torilor, acestea fiind elemente predefinite care se păstrează şi pentru tipurile abstracte.

Page 150: Programare Orientata Obiect Novac

12

• Supraîncărcarea operatorilor se realizează cu ajutorul unor funcţii membre sau prietene, speciale.

• Specificul lor constă în numele acestora.

• El se compune din cuvântul cheie operator şi unul sau mai multe caractere care definesc operatorul care se supraîncarcă.

Page 151: Programare Orientata Obiect Novac

13

Supraîncărcarea operatorului +pentru tipul COMPLEX

Complex Complex::operator +(Complex& z)//returneaza un obiect complex care este // sumadintre obiectul curent si cel //transmis prin z

{ Complex temp;temp.real=real+z.temp; temp.imag=imag+z.imag;return temp;}• În acest caz numele funcţiei este operator + , iar

în rest funcţia este identică cu funcţia membru adcomplex definită mai înainte.

Page 152: Programare Orientata Obiect Novac

14

• Efectul schimbării numelui din adcomplex în operator + este acela al supraîncărcării operatorului + pentru a admite ca operanzi obiecte de tip Complex.

• Deci, o expresie de forma a+b estelegală şi are ca rezultat un obiect de tip COMPLEX care reprezintă suma dintre a şi b.

Page 153: Programare Orientata Obiect Novac

15

• În locul expresiei a.adcomplex(b) care este mai puţin sugestivă vom utiliza :c=a+b;

• În mod analog putem supraîncărca operatorul – schimbând numele funcţiei fiend sccomplex cu operator –

• Se vor utiliza apoi expresii de forma a-b în locul apelului funcţiei sccomplex(a,b);

Page 154: Programare Orientata Obiect Novac

16

Supoper.cpp, Supoper1.cpp

Observaţii• Operatorii pot fi supraîncărcaţi prin funcţii

membre sau prin funcţii friend;• O diferenţa între cele două tipuri constă în

numărul de parametri;• Astfel funcţiile membru care supraîncarcă

operatori unari nu au parametri, iar cele care supraîncarcă operatori binari au un singur parametru;

• În cazul funcţiilor friend numărul parametrilor este egal cu n-aritatea operatorului care se supraîncarcă.

Page 155: Programare Orientata Obiect Novac

17

• La supraîncarcarea operatorilor pentru obiecte de tip abstract nu se face diferenţa între formele prefixate şi cele postfixate.

• În principiu, funcţiile membru care supraîncarcă un operator nu sunt statice cu excepţia operatorilor unari new şi delete care se supraîncarcă numai prin funcţii membru statice;

Page 156: Programare Orientata Obiect Novac

18

• Alţi operatori care prezintă particularităţi la supraîncărcare sunt parantezele, operatorul-> şi operatorul de atribuire =.

• Mai sus, am considerat supraîncărcarea operatorilor binari pentru cazul când ambii operanzi sunt de tip abstract COMPLEX;

• Se pune problema utilizării operatorilor respectivi şi cu operanzi diferiţi adică de forma:

• a+k, k+a, a-k, k-a unde:• k- variabilă de tip int, iar a obiect Complex.

Page 157: Programare Orientata Obiect Novac

19

• Există 2 soluţii pentru a utiliza expersii de această formă:

1. Supraîncărcarea operatorului + nu numai pentru operanzi de tip Complex, ci şi pentru operanzi diferiţi;

2. Conversia operandului care nu este de tip Complex într-un obiect de tip Complex, înainte de aplicarea operatorului. Acest lucru este destul de simplu dar nu întotdeauna eficient.

Page 158: Programare Orientata Obiect Novac

20

Soluţia 1• Pentru a legaliza expresii de forma:

a+k unde a este obiect Complex iar k o variabilă de tip int, putem adăuga o nouă funcţie operator membră sau friend de tipul:

Complex Complex::operator +(int k){ Complex ztemp;ztemp.real=real+k; ztemp.imag=imag;return ztemp;}Sau putem defini o funcţie friend cu acelaşi

efect:

Page 159: Programare Orientata Obiect Novac

21

Complex operator + (Complex& z1, intk)

{Complex ztemp;ztemp.real=real+k; ztemp.imag=imag;return ztemp;}

Page 160: Programare Orientata Obiect Novac

22

Adăugând una dintre aceste funcţii se pot utiliza instrucţiuni de forma :Complex a,b;int k;….b=a+k;b=a+123;

• Să observăm că funcţiile de mai sus implicăfaptul că primul operand este de tip Complexceea ce înseamnă că expresiile de formak+a 123+a

sunt ilegale.

Page 161: Programare Orientata Obiect Novac

23

• Pentru a accepta astfel de expresiieste necesar ca operatorul + să fie supraîncărcat în mod corespunzător, adică pentru expresii în care primul operand este de tip int şi al doilea este de tip Complex.

Page 162: Programare Orientata Obiect Novac

24

• O astfel de supraîncărcare se poate realiza dar numai printr-o funcţie friend deoarece în cazul funcţiilor membru, primul parametru este întotdeauna obiectul curent şi acesta nu poate fi de tip int.

• De aceea pentru a admite expresii în care primul operand este de tip int şi al doilea de tip Complex vom utiliza următoarea funcţie friend:

Page 163: Programare Orientata Obiect Novac

25

Complex operator + (int k, Complex z)// returneaza obiectul complex k+z{Complex ztemp;ztemp.real=z.real+k;ztemp.imag=z.imag;return ztemp;

}

Page 164: Programare Orientata Obiect Novac

26

• Din exemplu se vede că supraîncărcareaoperatorilor nu permite moştenireaproprietăţii de comutativitate a acestora;

• Astfel deşi operatorul + este comutativ pentru operanzi de tipuri predefinite, supraîncărcarea lui pentru expresii de forma a+k unde:- a este obiect de tip Complex- k este variabilă de tip int, nu este

valabilă pentru expresii de tip k+a.

Page 165: Programare Orientata Obiect Novac

1

FISIERE IN C++

Page 166: Programare Orientata Obiect Novac

2

Biblioteca standard a limbajului C++ oferă utilizatorului două ierarhii de clase pentru operaţii de I/E şi lucrul cu fişiere. Una are ca rădăcină clasa streambuf, iar cealaltă, clasa ios.

La bază se află conceptul de stream (flux). Prin stream se înţelege un flux de date de la sursă către o destinaţie sau consumator.

Clasa streambuf furnizează funcţii generale pentru lucru cu zonele tampon (bufere) şi permite tratarea operaţiilor de I/E fără a avea în vedere formatări complexe. Din clasa streambuf derivă clasele strstreambuf şi filebuf.

Page 167: Programare Orientata Obiect Novac

3

Clasa ios are un pointer către streambuf. Ea are date pentru a gestiona interfaţa cu streambuf şi pentru tratarea erorilor.

Din clasa ios derivă clasele istream pentru gestionarea intrărilor şi clasa ostream pentru gestionarea ieşirilor.

La prelucrarea fişierelor se folosesc obiecte ale clasei filebuf.

Sunt folosite următoarele clase:- ifstream folosită pentru operaţii de intrare (citire)

Page 168: Programare Orientata Obiect Novac

4

- ofstream folosită pentru operaţii de ieşire(scriere)

- fstream folosită pentru operaţii de intrare/ieşire (citire/scriere)

■ Pentru obiectele acestor clase se pot aplica funcţiile membru ale claselor de bază, inclusiv supraîncărcarea operatorilor de inserare şi extragere.

■ Prelucarea unui fişier începe cu deschiderea lui. În acest scop se poate proceda în 2 moduri:

Page 169: Programare Orientata Obiect Novac

5

1. Se utilizează funcţia open cu un obiect al uneia din clasele ifstream, ofstream sau fstream instanţiat fără parametri;

2. Se utilizează parametri pentru deschiderea fişierului la instanţierea obiectelor;

În primul caz, obiectele se instanţiază folosind constructori impliciţi;

De exemplu, fie instanţierea:ifstream fisier1;

Obiectului fisier1 i se ataşează un fişier concret la un apel al funcţieifisier1.open(...)

Page 170: Programare Orientata Obiect Novac

6

Funcţia open este definită în clasa fstreambase şi este supraîncărcată în clasele derivate din aceasta. Ea are prototipul:void open(char *fisier,int mod,int protectie);

Parametrul fisier este un pointer spre un şirde caractere care defineşte numele şiextensia fişierului care se deschide, precumşi calea spre fişierul respectiv, dacă nu se află în directorul curent.

Parametrul mod defineşte modul de deschi-dere al fişierului. În acest scop se pot folosi enumeratorii definiţi în clasa ios astfel:

Page 171: Programare Orientata Obiect Novac

7

in - fişierul se deschide în intrare (citire); out – fişierul se deschide în ieşire (scriere); ate – după deschiderea fişierului, poziţia

curentă în fişier este sfârşitul fişierului; acest mod se utilizează pentru a face căutări în fişier începând cu sfârşitul acestuia;

app – deschidere pentru a adăuga înregistrări trunc – dacă fişierul există, conţinutul lui se

pierde şi se crează un fişier nou. Acest mod este implicit când este prezentă opţiunea out (deschidere în scriere) şi este incompatibil cu opţiunile ate şi app;

Page 172: Programare Orientata Obiect Novac

8

nocreate – dacă fişierul există şi este prezen-tă opţiunea out, atunci deschiderea este admisă numai dacă se utilizează opţiunea ate sau app.

binary – fişierul se deschide pentru a putea fi prelucrat binar. În mod implicit fişierele se consideră că sunt prelucrate pe caractere (mod text).

La deschidere de fişier se pot folosi împreună mai multe opţiuni folosind operatorul sau logic (“|”)

Page 173: Programare Orientata Obiect Novac

9

■ Pentru obiectele clasei ifstream, opţiunea ineste implicită, iar pentru cele ale claseiofstream, opţiunea out este implicită.

Parametrul protectie defineşte modul de acces la fişier. În mod implicit acest parame-tru are valoarea zero şi aceasta înseamnă că fişierul respectiv nu are restricţii la acces.

Rezultatul operaţiei de deschidere poate fi testat cu ajutorul cuvâtului de stare al streamului pentru care s-a apelat funcţia open.

Page 174: Programare Orientata Obiect Novac

10

Exemple1. ifstream fisier;// se deschide fisierul fis.dat in citire

fisier.open(“fis.dat”,ios::nocreate);// se testeaza starea obiectului fisier dupa deschidere

if(fisier){// deschidere corecta

…}else{

…cout<<“Incident la deschidere fisier fis.dat\n”;…}

Page 175: Programare Orientata Obiect Novac

11

Exemple Opţiunea ios::in este implicită.

2. ofstream fis_iesire;//se deschide in scriere fisierul factura.dat

fis_iesire.open(“factura.dat”);if(!fis_iesire){ cout<<“Incident la deschidere;

…}

Page 176: Programare Orientata Obiect Novac

12

Exemple3. ofstream fis;//se deschide pentru adugare fisierul binar //stoc.dat

fis.open(“stoc.dat”,ios::app|ios::binary);// se testeaza starea obiectului fis dupa deschidereif(!fis){

cout<<“Incident la deschidere”;…}else {

…//deschidere corecta}

Page 177: Programare Orientata Obiect Novac

13

Cea de-a doua posibilitate de deschidere a unui fişier este folosirea parametrilor corespunzători la instanţierea obiectelor claselor ifstream, ofstream sau fstream.

În acest caz constructorul apelat pentru instanţierea obiectelor claselor amintite mai sus au aceeaşi parametri ca şi funcţia open:

nume_clasa(char *fisier,int mod, int protectie)unde:nume_clasa este ifstream, ofstream, fstream. Parametru protectie este şi în acest caz un

parametru implicit cu valoare zero.

Page 178: Programare Orientata Obiect Novac

14

Exemplele anterioare pot fi rescrise astfel1. ifstream fisier(“fis.dat”,ios::nocreate);

if(fisier){//deschidere corecta

…}else { cout<<“Incident la deschidere”;…}

2. ofstream fis_iesire(“factura.dat”);if(!fis_iesire){ cout<<“Incident la deschidere;

…}

Page 179: Programare Orientata Obiect Novac

15

Exemplul 3

ofstream fis (“stoc.dat”,ios::app | ios::binary);if(!fis){

cout<<“Incident la deschidere”;…}

else { …//deschidere corecta}

Page 180: Programare Orientata Obiect Novac

16

După deschiderea unui fişier se pot face prelucrări pe el;

După terminarea prelucrării, în conformitate cu modul în care a fost deschis, acesta trebuie să fie închis;

Închiderea se realizează cu funcţia close. Aceasta se apelează astfel:

obiect.close();sau

pobiect->close();unde:obiect – este o instanţă a uneia dintre clasele ifstream,

ofstream sau fstream.

Page 181: Programare Orientata Obiect Novac

17

În mod analog, pobiect este un pointer spre unul din tipurile implementate prin aceste clase.

Funcţiile membre get, getline, put, read şi write pot fi folosite pentru a realiza operaţii de intrare/ieşire cu acces secvenţial.

Accesul aleator se poate realiza folosind funcţiile membru specifice ale claselor ostream şi istream.

Clasa ostream are funcţiile membru seekp şi tellp care pot fi utilizate la realizarea accesu-lui aleator la scrierea înregistrărilor în fişiere.

Page 182: Programare Orientata Obiect Novac

18

În mod analog, clasa istream are funcţiile membru seekg şi tellg care pot fi utilizate la realizarea accesului aleator la citirea înregis-trărilor în fişiere.

Funcţia tellp returnează poziţia curentă din stream faţă de începutul lui. Are prototipul:long tellp();

Funcţia seekp realizează poziţionarea în streamul curent. Are prototipul:ostream&seekp(long n,seek_dir rel=beg);

unde:seek_dir se defineşte în clasa ios astfel:

Page 183: Programare Orientata Obiect Novac

19

enum seek_dir{beg,cur,end}; Aceşti parametri au următoarea semnificaţie:- n deplasament în număr de octeţi;- rel=beg deplasamentul se consideră faţă de

începutul streamului;- rel=cur deplasamentul se consideră faţă de

poziţia curentă din stream;- rel=end deplasamentul se consideră faţă de

sfârşitul streamului.

Page 184: Programare Orientata Obiect Novac

20

Funcţiile membre ale clasei istream au prototipuri şi semnificaţii similare;

long tellg();şi

istream&seelg(long n,seek_dir rel=beg); De menţionat că funcţiile tellp, tellg, seekp,

seekg se pot utiliza şi în legătură cu obiecte ale claselor istrstream, ostrstream şi strstream.

Page 185: Programare Orientata Obiect Novac

21

O altă funcţie utilă este gcount, funcţie membră a clasei istream.

Ea are prototipul:int gcount();

Returnează numărul de octeţi citiţi la ultima operaţie de intrare.

Page 186: Programare Orientata Obiect Novac

22

Aplicaţie: fismisc.cpp

Să se scrie un program care citeşte de la intrarea standard datele ale căror formate sunt definite mai jos şi le scrie în fişierul misc.dat din directorul curent.Fişierul este organizat binar, fiecare articol conţinând următoarele câmpuri:

100010123456mcablu electricIcantitatepreţcodumdenumiretip

Page 187: Programare Orientata Obiect Novac

23

Aplicaţie : fismisc1.cpp

Să se scrie un program care afişează articolele din fişierul misc.dat creat anterior , pentru tip=I.

I=intrariE=iesiriT=transfer

Page 188: Programare Orientata Obiect Novac

24

Aplicaţie: fistext.cpp

Să se scrie un program care citeşte şiruri de caractere şi le transferă pe disc.