Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




OBIECTE SI CLASE

c


OBIECTE sI CLASE

11.1. Diversitatea datelor

În multe cazuri, se confunda diversitatea datelor cu complexitatea datelor. Diversitatea datelor pune în evidenta tipurile de date care participa la construirea unei structuri: ponderea pe care fiecare dintre tipuri o are în structura, influenteaza indicatorul de diversitate D, care are forma:



unde:

n - numarul de tipuri distincte care intra în alcatuirea structurii de date;

fi - frecventa 929c27j aparitiilor tipului Ti.

Restrictii asupra definirii obiectelor în limbajul C/C++.

Tipul de data obiect, se defineste numai la începutul programului. Elementele ce sunt definite într-o data de tip obiect, sunt fisierele.

Obiectele nu se definesc în functii, proceduri sau în programul principal. Observam ca tipul de date obiect este global.

Astfel, prin structura stud definita prin:

struct stud

;

se identifica numarul de tipuri n = 2 (sunt utilizate 8 date de tip integer si 4 date de tip string).

Indicatorul de diversitate:

D = 8 log2 8 + 4 log2 4 = 32

Complexitatea datelor ofera prin indicatorii utilizati, o imagine mai exacta asupra dependentelor ce se creaza între partile ce alcatuiesc structurile de date. Daca se asociaza unei structuri, arce prin care se marcheaza modalitati de traversare, indicatorii de complexitate preiau si aceste elemente în calcul. Astfel, indicatorii de complexitate au forme analitice în care se include:

- numarul tipurilor de date;

- numarul datelor din fiecare tip;

- numarul arcelor care leaga datele.

De exemplu, un indicator de complexitate, simplu dar sugestiv este:

C = n log2 n + m log2 m

unde:

n - numarul tipurilor distincte de date;

m - numarul de arce.

De exemplu, pentru lista liniara simplu înlantuita:

struct lista

;

în care cele 17 elemente contin doua tipuri de date, iar între elemente se afla câte un arc, complexitatea este:

C = 2 log22 + 16 log216 = 66

În programe, se vorbeste de structuri de date cu aceeasi diversitate/complexitate. Ori de câte ori se întâlnesc multe structuri cu valori ale indicatorilor D si C asemanatoare, se încearca analizarea posibilitatii de optimizare, în sensul eliminarii structurilor de date ce pot fi înlocuite cu structuri de date deja existente.

Apare problema: fiecare limbaj în care sunt definite tipuri de date, accepta structuri cu o anumita diversitate si complexitate depasirea unor nivele determinând ineficienta programelor. Singura modalitate de a depasi aceste situatii, consta în construirea de noi tipuri de date, altele decât tipurile derivate.

Noile tipuri de date trebuie sa se bucure de proprietati precum:

- posibilitatea de a cuprinde pe lânga tipurile de baza si alte tipuri ce se asimileaza datelor.

- capacitatea de a accepta definiri de reguli si raporturi, cu alte componente de acelasi fel sau alte componente ale programelor.

În capitolul destinat pointerilor, s-a facut afirmatia ca pointerii sunt date. De asemenea, pointerii spre functii sunt date. Textele sursa sunt date, precum si textele executabile ale programelor sunt date. Se vorbeste de tipul de data pointer spre functie, de tipul de data program sursa si de tipul de data program executabil. Pe lânga tipurile de date descrise anterior, au mai aparut si aceste trei tipuri derivate.

Apare problema efectuarii unui salt calitativ si anume acela al includerii unuia dintre aceste trei tipuri în structuri. Noul tip de data, poarta numele de obiect si a determinat o revolutie în activitatea de programare.

Discipline ca "Programarea Orientata pe Obiecte - POD", "Baza de Date Orientate pe Obiecte", Proiectarea Orientata pe Obiecte", vin sa puna în evidenta influenta necesara asupra conceptiei noi de rezolvare a problemelor, prin utilizarea curenta în programe a acestui tip de data.

Un alt exemplu

Manualele de programare, articolele din revistele de specialitate în care se încarca prezentarea programarii orientate pe obiecte, încep si dezvolta acelasi exemplu de grafica, cu un cerc. Sugestiv exemplu, dar prea este singurul!

În continuare, se defineste o alta problema, care propune o abordare a rezolvarii prin definirea si folosirea de obiecte.

Se considera datele privind stocurile de materiale la nivelul zilelor dintr-o luna. Lunar se întocmeste o situatie ce contine valoarea stocurilor si total valoric la nivelul lunii. Trimestrial, se întocmeste si un raport centralizator, care preia totalurile fiecarei luni. Anual se întocmeste un centralizator care preia totalurile fiecarui trimestru.

Observam de exemplu, ca în luna iunie se obtine atât raportul lunar, corespunzator lunii, cât si raportul trimestrial, care preia totalurile lunilor aprilie, mai si iunie.

De asemenea, observam ca în luna decembrie, pe lânga rapoartele lunar si trimestrial, se preiau totalurile din trimestrele 1, 2, 3 si 4 si se obtine valoarea anuala a stocurilor de materiale.

Deci:

a)      pentru raportul lunar, exista datele stocurilor zilnice si functia care calculeaza totaluri la nivel de luna;

b)      pentru sfârsitul de trimestru, se calculeaza raportul lunar (a) si se preiau date pentru totalul trimestrial;

c)      pentru sfârsitul de an, se calculeaza raportul lunar (a), raportul trimestrial (b) si se preiau date pentru raportul anual

Pentru rezolvarea acestei probleme, trebuie sa procedam astfel:

- se defineste o matrice a[31][4]; coloana a[i, 0] reprezinta valoarea stocurilor initiale la toate materialele în ziua a i-a din luna; coloana a[i, 1] reprezinta valoarea intrarilor; coloana a[i, 2] reprezinta valoarea iesirilor si coloana a[i, 3] contine dupa efectuarea calculelor, valoarea stocurilor finale ale materialelor în ziua a i-a.

- se definesc variabilele tlsi, tlin, tlsf, ce corespund totalurilor pentru cele 4 coloane ale matricei a[31][4];

- se construieste functia pentru calculul celor 4 totaluri;

- se definesc matricea b[3][4] si datele ttsi, ttin, ttie, ttsf ce corespund, respectiv, totalurilor din cele trei luni si totalurilor la nivel de trimestru; se construieste functia care face însumarile;

- se definesc matricea c[4][4] si variabilele tasi, tain, taie, tasf, pentru totalurile celor patru trimestre si respectiv, pentru totalurile anuale; se construieste functia care face însumarile;

Se observa ideea, de a grupa datele lânga functiile care le prelucreaza, aspect normal daca se are în vedere ca nu toate datele sunt operanzi în toate functiile.

Se contureaza ideea definirii a trei obiecte:

- obiectul numit situatie_lunara;

- obiectul numit situatie_trimestriala;

- obiectul numit situatie_an.

Programul care prelucreaza datele astfel organizate este:

//Program situatii_obiect

#include <iostream.h>

#include <malloc.h>

typedef int mat1[31][4];

typedef int mat2[3][4];

typedef int mat3[4][4];

class situatie_lunara

;

class situatie_trimestru

;

class situatie_an

;

situatie_lunara luna[12]; // variabile utilizate

situatie_trimestru trim[4];

situatie_an an;

int m1, m, i, j, k;

void situatie_lunara::citeste_date(int ij)

};

void situatie_lunara::calcul_lun( int ij)

};

void situatie_trimestru::calcul_trim(int kr)

};

void situatie_trimestru::initializare_trimestru(int kr)

};

void situatie_an::initializare_an( int k)

;

void situatie_an::calcul_an( int k)

};

main()

for( i = 0; i<m1;i++)

for( k = 0; k<m;k++)

an.initializare_an(j) ;

an.calcul_an(k) ;

cout<<"\n TOTAL anual.... stoc_in = "<<an.zasi<<" intrari = "<<

an.zain<<" iesiri = "<<an . zaie<<" stoc final = "<<

an.zasf;

cin>>m;

}

Obiectul situatie_lunara, este definitor pentru obiectul situatie_trimestru. Obiectul situatie_trimestru este definitor pentru obiectul situatie_an.

Elementele obiectivului definitor, se regasesc în obiectul definit. În mod natural, pentru calculul totalurilor la nivel de trimestru, sunt necesare datele lunilor, iar pentru calculul la nivelul întregului an, sunt necesare datele trimestrelor.

În program, sunt definite proceduri care opereaza cu datele încapsulate ca si ele, în fiecare obiect.

Daca pentru prelucrare, se construiesc functii care returneaza pointeri spre diferite tipuri de structuri, prin modificari adecvate se obtine o varianta a programului de mai sus.

//Program functii_obiect

#include <iostream.h>

#include <malloc.h>

typedef int mat1[31][4];

typedef int mat2[3][4];

struct str1

;

struct xx1

;

struct yyt

;

struct zza

;

typedef mat1 * pmat1;

typedef xx1 * pxx1;

typedef str1 * pstr1;

typedef yyt * pyyt;

typedef zza * pzza;

class situatie_lunara

;

class situatie_trimestru

;

class situatie_an

;

situatie_lunara luna[12];

pstr1 ppstr[12];

pxx1 ppxx1[12];

situatie_trimestru trim[4];

int m1, n, m, i, j;

situatie_an an;

pyyt ppyyt[4];

pzza ppzz;

pyyt pyt1;

pstr1 situatie_lunara::citire_date(int si)

cout<<"\n Numar zile: ";

cin>>nn;

ps = &luna[si].aa;

for (ii = 0;ii<nn;ii++)

return ps;

};

pxx1 situatie_lunara::calcul_lunar(pstr1 ps)

return px;

};

pyyt situatie_trimestru::calcul_trim(pstr1 pp)

return py;

};

pzza situatie_an::calcul_an(pyyt py)

}

return pa;

};

main()

for( i = 0; i<3*m;i++)

for(i = 0; i<m;i++)

for(j = 0; j<3;j++)

ppzz = an.calcul_an(pyt1);

cout<<"\n TOTAL :"<<ppzz->zasi<<" "<<ppzz->zain<<" "<<ppzz->zaie<<

"stoc final = "<<ppzz->zasf;

}

11.2. Pointeri spre obiecte

Ca si în cazul celorlalte tipuri de variabile, tipului de data obiect i se aloca dinamic memorie. Pentru aceasta trebuie:

definit obiectul în partea de program TYPE ;

definit un pointer spre tipul obiect definit anterior ;

definita variabila pointer în parte de program VAR ;

alocata memorie cu functia NEW () si initializata variabila pointer ;

utilizarea membrilor obiectului folosind operatori de referire.

si în cazul definirii obiectelor, este posibila referirea pe mai multe nivele si evaluarea expresiilor de referire folosind regulile deja cunoscute.

În exemplul anterior, la definirea obiectului s-a folosit o data de tip adecvat. Apare firesc întrebarea : este posibila utilizarea unui pointer spre acel tip de data si alocarea dinamica a memoriei? Raspunsul este afirmativ.

Pentru efectuarea alocarii dinamice a memoriei pentru o componenta operând dintr-un obiect, care la rândul sau este alocat dinamic, se foloseste functia implicita numita CONSTRUCTOR () , iar pentru efectuarea dealocarii se foloseste functia, de asemenea implicita, DESTRUCTOR ().

Se considera tot aplicatia de calcul a stocurilor, cu folosirea de aceasta data a alocarii dinamice de memorie pentru obiecte:

//Program situatii_obiect

#include <iostream.h>

#include <malloc.h>

typedef int mat1[31][4];

typedef int mat2[3][4];

typedef int mat3[4][4];

class situatie_lunara

class situatie_trimestru

class situatie_an

typedef situatie_lunara * p_luna;

situatie_lunara luna[12]; // variabile utilizate

situatie_trimestru trim[4];

situatie_an an;

int m1, m, i, j, k;

p_luna pp_luna[12];

void situatie_lunara::citeste_date(int ij)

void situatie_lunara::calcul_lun( int ij)

void situatie_trimestru::calcul_trim(int kr)

void situatie_trimestru::initializare_trimestru(int kr)

void situatie_an::initializare_an( int k)

void situatie_an::calcul_an( int k)

main()

for( i = 0; i<m1;i++)

for( k = 0; k<m;k++)

an.initializare_an(j) ;

an.calcul_an(k) ;

cout<<"\n TOTAL anual.... stoc_in = "<<an.zasi<<" intrari = "<<

an.zain<<" iesiri = "<<an . zaie<<" stoc final = "<<

an.zasf;

cin>>m;

11.3 Functii virtuale

Pâna acum s-a vazut ca variabilele de tip obiect reprezinta zone de memorie cu o structura ce include si pointeri spre functii. Dupa aceea s-a pus în evidenta modul de referire a variabilelor de tip static a membrilor acestora - operanzi sau functii.

S-au definit pointeri spre obiecte si s-a efectuat alocare dinamica, ca pentru o variabila de tip STRUCT. S-au definit functii de tip CONSTRUCTOR () si DESTRUCTOR (), ce ofera posibilitatea de a aloca /elibera dinamic memorie, pentru a initializa pointeri definiti ca membri în structura de date de tip obiect. Zonele de memorie alocate corespund unor operanzi.

În capitolul destinat pointerilor, se specifica existenta pointerilor spre functie, care prin initializari adecvate determina succesiuni de prelucrari extrem de mobile si de complexe.

Cum în structura de date de tip obiect, sunt definite functii si proceduri, apare în mod firesc întrebarea daca se definesc pointeri spre acestea, daca acesti pointeri sunt initializati în timpul executiei.

Raspunsul este afirmativ si rezolvarea este data cu ajutorul functiilor virtuale, cam pretentios numite astfel.

Functiile de tip constructor sunt în continuare de tip static, progrmatorul putând defini în cadrul structurilor obiect proceduri, functii si functii de tip destructor de un nou tip, numit VIRTUAL.

Functiilor virtuale, li se conserva informatii privind pozitia pe care o ocupa (adresa primei instructiuni executabile), într-o structura de tip masiv unidimensional, atasat obiectului.

Daca în timpul executiei, se doreste activarea unei functii virtuale sau a alteia, se atribuie continutul ce corespunde respectivei functii din masivul unidimesional, unei variabile de tip pointer spre obiect si prezenta acestuia într-o secventa executabila determina prelucrarea.

Fie obiectele O1, O2, . . . Ok, si masivele unidimensionale A1, A2, . . . Ak, având n1, n2, . . . nk componente, functie de elementele ce alcatuiesc structura obiectelor carora le corespund.

Presupunând ca fiecare obiect Oi, dispune de definirea unor functii s-au proceduri virtuale, pij, j = 1, 2, ., mk, cu mk < nk, initializarea vectorului Ai se efectueaza:

cont Ai [ni - mi + j] = adr (pij)

Daca se definesc variabilele v1, v2, ..., vk pointeri, respectiv spre obiectele O1, O2, . . . , Ok, atribuiri de forma:

vi = cont (Ai [h]), h [ni - mi + 1 , ni]

secventele:

v1

v2

vn

corespund lansarii în executie a unor functii.

Mai mult, datorita faptului ca aceasta categorie de pointeri spre obiecte corespunde unui tip mai general, regulile de conversie de tip sunt la fel de riguros definite.

Variabilele de tip pointer spre obiect, sunt initializate cu adresele membrilor - operanzi sau functii. Pointerii spre functii, alcatuiesc o multime omogena, fapt care permite efectuarea de atribuiri oarecare.

De exemplu, variabila vi este definita ca pointer spre obiectul Oi, iar componenta Ak [r] contine adresa unei proceduri virtuale Pkr, definite în obiectul Ok.

Atribuirea:

vi = cont (Ak [r]) ;

este corecta, mai mult, nu necesita conversii.

În unele situatii, pentru a mentine aceasta cerinta de necesitate a conversiilor, se impune ca functiile virtuale cu care se atribuie aceeasi variabila pointer, sa fie de acelasi tip, adica sa întoarca acelasi rezultat, stiut fiind faptul ca tipul de data program executabil - functie, este marcat prin ceea ce el returneaza.

În concluzie, observam ca modul de lucru cu obiecte, realizeaza deziderate mai vechi ale programatorilor:

încapsularea într-un obiect a operanzilor si operatorilor (functii, proceduri);

mostenirea - posibilitatea de a prelucra într-un anumit obiect care se defineste, operatori si operanzi ai obiectelor definite anterior;

polimorfismul - prin care un nume de functie se redefineste într-o ierarhie de obiecte si se foloseste conform algoritmilor de prelucrare.

Se observa ca, variabilele pointer permit lucrul cu toate tipurilor de date, putându-se realiza constructii fie complexe, fie bizare, iar singura conditie de apreciere, este ca una dintre caracteristicile textului sursa elaborat, sa se amelioreze.

Deci, în versiunile ulterioare ale limbajelor, implementarea lucrului cu obiecte este vazuta ca extensie, etapele urmatoare punând în evidenta faptul ca toate tehnicile de programare se îndreapta spre utilizarea obiectelor.



Document Info


Accesari: 710
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2024 )