|
variate ale acestor clase de obiecte.Nu toate functiile unui astfel de
|
səhifə | 3/18 | tarix | 12.09.2018 | ölçüsü | 1,36 Mb. | | #81721 |
| variate ale acestor clase de obiecte.Nu toate functiile unui astfel de
obiect sunt virtuale.Constructorul,destructorul si grupul principal de
functii sunt definite,astfel ca obiectul va fi usor de materializat si
apelat.Se includ functii virtuale doar pentru operatiile care urmeaza
sa fie executate in context diferit sau cu tipuri de date variabile de
la un utilizator la altul.Prin acest mecanism,se asigura o flexibilitate
extrem de mare in modul de apelare si utilizare al acestor clase de
obiecte.Practic,operatiile executate de procesor se reduc la minimum,in
schimb,creste volumul de munca in etapa de proiectare si programare.
Exista un numar destul de mare de unitati care contin astfel de clase
de obiecte(si numarul lor este in continua crestere).Clasele de obiecte
dezvoltate si acceptate de catre firma Microsoft sunt grupate intr-o
biblioteca denumita MFC (Microsoft Foundation Class Library).Daca doriti
sa dezvoltati astfel de biblioteci,respectati cu strictete standardul
de limbaj (si conventiile de notatie).
O alta notiune generatoare de confuzii este cea de vizibilitate(scope).
Vizibilitatea locala se refera la faptul ca un anumit tip de data nu poate
fi utilizat decat in blocul de program pentru care a fost declarat.Cel
mai clar exemplu sunt argumentele unei functii (parametrii).In mod similar
datele declarate in interiorul unei functii nu au vizibiliate in afara
functiei respective.
Etichetele au vizibiliate limitata strict la functia in care sunt
incluse.Nu se poate face salt la o astfel de eticheta din exteriorul
functiei sau din alt modul de program.
Vizibilitatea la nivel de fila de program se numeste vizibilitate glo-
bala.Toate datele declarate in afara functiilor au vizibilitate globala.
Membri unei clase sau cei ai unui obiect se pot apela la fel ca si
membri unei structuri,cu ajutorul operatorului de selectie (punctul . sau
.* si ->* in cazul in care membrii sunt din tipul pointer).Accesul la
membrii unui obiect este determinat si prin specificatorii de acces:
private=vizibilitate locala,public=vizibilitate globala sau protected=
vizibilitate locala si pentru clasele sau functiile declarate friend.
In mod implicit,membrii unui obiect au vizibilitate locala (se pot
apela intre ei dar nu pot fi apelati din afara obiectului.In cazul in
care o clasa sau o functie este declarata "friend",aceasta functie va
putea avea acces si la membri obiectului declarati private sau protected.
Ca rezultat,atunci cand nu exista decat vizibilitate locala,se poate uti-
liza acelasi identificator in mai multe blocuri independente de program
(Exemplu: variabila X poate fi utilizata in doua sau mai multe functii).
Limbajul C++ permite chiar si supraincarcarea identificatorilor.Cu alte
cuvinte,in program pot exista mai multe functii cu acelasi nume,cu condi-
tia sa utilizeze argumente diferite (parametri diferiti).
Exemplu: pot exista doua functii denumite MAX() daca prima opereaza cu
numere intregi Max(n:integer) iar cea de a doua opereaza cu numere in
virgula mobila Max(n:float).Compilatorul va recunoaste si va apela functia
corecta in functie de parametrul sau.Pe cat posibil,se va evita si supra-
incarcarea identificatorilor pentru a nu crea ambiguitati.
-13-
Un program poate fi continut in una sau mai multe file (module).In
urma compilarii,se creaza legaturile necesare dintre file (module) astfel
incat executia programului sa inceapa cu modulul care contine functia
main().Formula generala pentru functia main () este:
int main( int argc[,char *argv[][,char *envp[] ] ]);
In mod curent,toate codurile se introduc in corpul functiei main().Daca
programul contine si functii declarate in afara functiei main(),acestea
vor trebui apelate explicit (nu pot fi executate automatic).
Limbajul C++ accepta toate tipurile de date din limbajul C,la care se
adauga tipul class si toate tipurile derivate (clase derivate din cele
standard,clase obtinute prin combinarea claselor standard,clase nou
definite si inregistrate etc.).
In limbaj C++ se poate face conversia intre diferitele tipuri de date
(Exemplu: int in float,pointer in string etc.).Conversiile intre tipurile
fundamentale de date poarta numele de "Standard Conversions" (conversii
standard).Aceste conversii pot fi efectuate de compilator fara nici un
alt program auxiliar.Pentru conversiile realizate intre tipurile de date
definite de utilizator,este necesar si un program sau un algoritm special
care sa realizeze conversia (nu se poate face automat).
Prin gruparea de cuvinte cheie,identificatori,operatori si punctuatori
se formeaza expresii.Expresiile formate in limbaj C++ pot fi:
1.Expresii primare: -sunt formate dintr-un singur element de limbaj la
care se adauga operatorul scope (::).
2.Expresii postfix: -sunt expresii primare urmate de un operator
3.Expresii unare: -sunt expresii in care operatorii actioneaza asupra unui
operand unic.
4.Expresii binare: -sunt expresii in care operatorul actioneaza asupra a
doi operanzi.
5.Expresii ternare: -sunt expresii in care exista si un operator conditio-
nal,astfel incat operatorul ternar actioneaza asupra celor doi ope-
ranzi doar daca este indeplinita o anumita conditie.
6.Expresii constante: -sunt expresii formate exclusiv din date constante.
7.Expresii cu conversii explicite: -utilizeaza si conversiile standard.
8.Expresii cu pointer spre membrii unui obiect -utilizeaza si pointeri.
9.Expresii de tip casting: -conversii de tip Type-Cast Conversions
10.Expresii tip Run-Time Type Information -sunt expresii in care tipul de
data sau tipul unui anumit obiect este determinat doar in timpul
executiei programului.
Formula generala a unei expresii este de genul:
Specificator Modificator Tip de data Identificator Operator ....
Expresiile se utilizeaza pentru a forma instructiuni si comenzi.Pot fi
identificate mai multe tipuri de instructiuni:
1. Instructiuni expresie :-evalueaza rezultatul unei expresii.
2. Instructiuni nule: -tin locul unei instructiuni viitoare.
3. Instructiuni compuse:-contin expresii complexe ordonate prin paranteze.
4. Instructiuni de selectie: -selecteaza un anumit cod pentru executie.
5. Instructiuni iterative: -determina repetarea unei operatii.
6. Instructiuni de salt: -transfera executia la alta locatie din program .
7. Instructiuni declaratie: -introduc elemente noi in program.
8. Instructiuni de tratare a erorilor: executa exceptiile pentru erori.
-14-
CLASE SI OBIECTE
Acest manual are ca scop prezentarea simplista a conceptului de pro-
gramare orientata spre obiect si a modului de implementare a acestui
concept in cazul limbajului C++.
Obiectele sunt structuri de date complexe,de dimensiuni variabile,
utilizate in programare pentru a permite operatii cu blocuri mari de
date,sau pentru a utiliza un grup de functii specializate care opereaza
asupra unui bloc de date.Nu are rost sa utilizati obiecte,doar de dragul
obiectelor.Exemplele din manual,vor prezenta doar elemente sumare ale
obiectelor si notiunile strict elementare.Pentru informatii suplimentare
puteti consulta manualele de specialitate.
Pentru formarea structurilor de date se pot utiliza tipurile: union,
struct si class.Union si struct au fost prezentate impreuna cu limbajul C
(vezi si manualul: "Limbajul C si C++ ABC-doar ").
Tipul de data class,este asemanator cu tipul struct,dar permite si
includerea unor functii locale in corpul structurii.In mod obisnuit(dar
nu obligatoriu),o astfel de structura de date va include unul sau mai
multi membri banali (diverse tipuri de date) si trei sau mai multe functii
specializate,care opereaza asupra datelor din structura.
Dintre functii,cea care initializeaza obiectul poarta numele de con-
structor iar cea care sterge obiectul din memorie poarta numele de des-
tructor.Restul functiilor executa operatiile necesare asupra datelor.
EXEMPLU: (vezi si clpus4.cpp)
#include
#include
class obiect1
{ public: int a; };
int main()
{ obiect1 a;
a.a=10;
cout << "valaorea returnata este: ";
cout << a.a;
sleep(3);
return 0;
}
Exemplul de mai sus contine cel mai simplu obiect posibil.Clasa obiect1
este declarata cu un singur membru,denumit "a",care este o variabila de
tip int.Clasa nu are nici constructor,nici destructor,nici alte functii,
ci doar un singur membru de tip variabila.Practic este aproape identic
cu o variabila de tip int.Pentru a putea utiliza acest tip de data,trebuie
creata o instanta a clasei,adica un obiect.In blocul functiei main() am
declarat on obiect din clasa obiect1 denumit tot a.Acest lucru este po-
sibil deoarece variabila a din clasa obiect1 este locala si nu are vizi-
bilitate in afara structurii.Apoi am utilizat operatorul "punct" pentru
a apela membrul obiectului si am atribuit acestuia o valoare oarecare.
Pentru a afisa pe ecran valoarea atribuita,am utilizat cout si opera-
torul de insertie in stream-ul de iesire.
Acest exemplu prezinta cea mai simpla operatie cu o data de tip obiect.
Chiar si in aceasta forma elementara,obiectul a respecta toate regulile
si toate conventiile referitoare la clase si obiecte.
-15-
Prin declararea unei clase noi,se introduce in program un nou tip de
data.Numele fiecarei clase trebuie sa fie unic,cel putin pentru programul
in care se va utiliza clasa respectiva.O clasa poate fi inclusa in alta
clasa,sub forma de membru al clasei respective.In acest caz,clasa va
avea vizibilitate doar in interiorul clasei in care este continuta.Dupa
delcararea unui clase,aceasta va funtiona ca orice alt tip de data din
program.Prin declararea unei variabile din tipul respectiv de data se
obtine o instanta a clasei respective,adica un obiect.
Membrii unei clase pot fi: date simple din orice tip,functii,alte clase,
enumerari,campuri de tip BitMap,clase si functii de tip friend sau tipuri
de date nou declarate (fara instante materializate).
Daca membrul unei clase este de tip functie,se va putea apela la fel
ca orice alt membru al clasei prin operatorul punct (.) sau (->).Daca o
clasa contine mai multe functii,acestea se vor putea apela intre ele
direct,fara a specifica numele clasei si operatorul de selectie,dar numai
in interiorul clasei respective.Pentru a putea fi apelate si din exterio-
rul obiectului,functiile trebuiesc declarate cu specificatorul de acces
"public".Exceptie fac functiile si clasele declarate "friend",care vor
putea avea acces si la mebrii protejati ai claei respective.
Declararea unui membru de tip functie se face la fel ca si pentru membrii
de tip data:
EXEMPLU: (vezi si cplus5.cpp)
#include
#include
class obiect1
{ public: int a;
int arie()
{ a=a*a;
return a;
};
}
int main()
{
obiect1.b;
b.a=7;
b.a=b.arie();
cout << "membrul apelat are valoarea: \n";
cout << b.a;
getch();
}
In exemplu de mai sus,clasa obiect1 are un membru simplu si un membru de
tip functie.Am declarat obiectul b din clasa obiect1 si am initializat
valoarea lui a(deoarece clasa nu are un constructor implict).Apoi am
apelat functia si am returnat valoarea obtinuta.
Pentru a simplifica operatiile asupra obiectelor,se obisnuieste ca
fiecare clasa sa contina si doua functii denumite constructor si respectiv
destructor.Constructorul are rolul de a initializa datele din obiectul
declarat,iar destructorul are rolul de a efectua operatiile de eliberare
a memoriei,in momentul in care obiectul nu mai este necesar.Constructorul
este apelat automat in momentul in care este creat un obiect din clasa
respectiva,astfel incat nu mai este necesar apelul explicit.
-16-
Pentru declararea constructorului se utilizeaza acelasi nume ca si
pentru clasa sa.Orice functie declarata cu numele clasei va fi interpre-
tata de compilator drept constructor al clasei respective.O clasa poate
avea unul sau mai multi constructori.Pentru a face diferenta dintre
acestia,este necesar sa utilizeze parametrii diferiti (pentru a permite
procedeul de supraincarcare a identificatorilor).Datorita faptului ca au
identificator comun cu cel al clasei lor,apelul constructorilor in afara
clasei se va face cu operatorul de scope :: prin care se specifica faptul
ca se doreste accesul la variabila globala cu numele respectiv.
Atunci cand o clasa are constructor,orice obiect derivat din clasa
respectiva va apela automat constructorul pentru a fi initializat cu
valorile respective(in momentul crearii).
EXEMPLU: ( vezi si cplus6.cpp )
#include
#include
class obiect1
{ public: int a;
obiect1(){ a=9; };
};
int main()
{
obiect1 b;
cout << "membrul apelat are valoarea: \n";
cout << b.a;
getch();
}
In exemplul de mai sus,se observa ca variabila a este gata initializata
in momentul formarii obiectului b si poate fi utilizata direct,ca atare.
In mod curent,constructorul nu este apelat decat in momentul in care se
construieste un obiect din tipul respectiv.Daca in clasa respectiva exista
un numar mare de date,din tipuri diferite,se poate utiliza cate un con-
structor diferit pentru fiecare tip de data,astfel incat obiectul derivat
sa contina toate datele gata initializate.
In mod curent,un obiect poate fi creat global (in afara functiilor),
local (in interiorul unei functii sau a unui modul),dinamic (cu ajutorul
operatorului New),temporar (cu existenta efemera),sub forma de membru al
unei alte clase,sau ca obiect drivat din alta clasa ( la care se adauga
date si functii noi).
Pentru obiectele utilizate doar de d-voastra,nu este necesar sa res-
pectati toate regulile de administrare a memoriei.Daca realizati insa
clase de obiecte si biblioteci DLL care contin clase de obiecte,pe care
doriti sa le poata utiliza si alti programatori,este esential ca obiectele
create din clasa respectiva sa fie initializate (aplicabile direct) si
respectiv sa fie eliberate complet din memorie cu ajutorul destructorului.
Destructorul este cealalta functie speciala a unei clase,utilizata tot
pentru organizarea si administrarea memoriei.Destructorul are rolul invers
fata de constructor,adica desface obiectul in datele componente si ape-
leaza functiile necesare pentru eliberarea memoriei.Destructorul se decla-
ra prin conventie,tot cu numele clasei,dar precedat de semnul tilda (~).
Daca nu exista un destructor declarat,compilatorul va crea un destructor
implicit care este apelat automat la eliberarea obiectului.
-17-
EXEMPLU: (vezi si cplus7.ccp)
#include
#include
class obiect1
{ public: int a;
obiect1() { a=9; };
~obiect1() { a=0; );
};
int main()
{
obiect1 b;
b.~obiect1();
cout << "membrul apelat are valoarea: \n";
cout << b.a;
getch();
}
In exemplul de mai sus,constructorul initializeaza a la valoarea 9 iar
destructorul aduce a la valoarea zero.Exemplul prezinta si modul de
apelare a destructorului.In mod normal,destructorul nu este apelat ca
o functie oarecare ci este apelat pentru a elibera memoria.In exemplul
de mai sus,pentru a elibera memoria se poate utiliza o functie de genul
free() sau delete().In acest caz,dupa apelarea destructorului nu se
mai pot apela membrii obiectului deoarece se va returna un mesaj de
eroare (valoare nedefinita).
Daca obiectul este complex,se pot utiliza etape succesive pentru
dealocarea fiecarui membru.
Nici constructorul si nici destructorul nu returneaza valori.Nu se
utilizeaza acest tip de functii pentru operatii obisnuite (chiar daca
este posibil) pentru a nu deruta compilatorul si pentru ca programele sa
poata fi verificate si depanate automat(exista programe de analiza care
apeleaza automat constructorul sau destructorul obiectelor pentru a
verifica ce efect au asupra memoriei de operare).
Este posibil ca un constructor sa fie doar declarat,iar definitia sa
fie introdusa in afara clasei.In acest caz,trebuie utilizat operatorul
scope (::) pentru a face distinctia dintre clasa si constructorul sau:
EXEMPLU: ( vezi si cplus8.cpp )
#include
#include
class obiect1
{ public: int a;
obiect1();
};
obiect1::obiect1() { a=33; };
int main()
{ obiect1 b;
cout << "membrul apelat are valoarea: \n";
cout << b.a;
getch();
}
Acest gen de declaratie,urmat de definitie,este utilizat mai ales atunci
cand definitia este destul de lunga (pentru a vedea unitar tot obiectul).
-18-
Orice declaratie si definitie inclusa in constructor va fi executata
la crearea fiecarui obiect.Din acest motiv,este bine ca expresiile uti-
lizate in constructor sa fie cat mai scurte si sa introduca doar datele
absolut necesare.Nu se vor utiliza comentarii sau explicatii si operatii
asupra valorilor initializate.Daca este necesar,se va adauga o functie
speciala,pentru a executa operatia respectiva:
EXEMPLU: (vezi si cplus9.cpp)
#include
#include
class obiect1
{ public: int a;float b,c;
obiect1(){ a=9; b=13.2345; c=0; };
float fun1() { c=a*b; return c; };
~obiect1() { a=0;b=0;c=0 };
}
int main()
{
obiect1 numar;
numar.c=numar.fun1();
cout << "membrul apelat are valoarea: \n";
cout << numar.c;
numar.~obiect1();
getch();
}
In mod similar,pentru un obiect care opereaza cu date de tip text:
EXEMPLU: (vezi si cplus10.cpp )
#include
#include
#include
#include
class obiect1
{ public: char *text;
obiect1() { text="Cuvant_de_control"; };
~obiect1() { text=""; };
};
int main()
{
obiect1 t1;
cout << "Introduceti un cuvant oarecare: \n";
cin >> t1.text;
cout << "cuvantul inversat este: \n";
cout << strrev(t1.text);
cout << " \n\n Apasati orice tasta ! ";
getch();
t1.~obiect1();
}
In mod similar,puteti dezvolta obiecte complexe,pentru efectuarea de
operatii matematice sau pentru prelucrarea textelor.Este bine sa verifi-
cati intotdeauna daca destructorul a eliberat complet memoria.Nu va bazati
Dostları ilə paylaş: |
|
|