1.CONCEPTUL DE CLASA SI OBIECT 1

2.FUNCTII MEMBRE INLINE 1

3.CONSTRUCTORI 1

4.CONSTANTA ASOCIATA UNEI CLASE 1

5.COSTRUCTOR DE COPIERE 1

6.OBIECTE CU EXTENSII IN MEMORIA DINAMICA1

7.DESTRUCTOR 1

8.POINTER THIS 1

9.FUNCTII DE ACCES 1

10.POINTERI LA OBIECTE 1

11.OPERATORUL NEW 1

12.OPERATORUL DELETE 1

13.MASIVE DE OBIECTE 1

14.TRANSFERUL OBIECTELOR IN / DIN FUNCTII 1

15.CLASE INCLUSE (IMBRICATE )1

16.OPERATORUL DE REZOLUTIE 1


CONCEPTUL DE CLASA SI OBIECT

In C++ clasa :

-formeaza baza programarii orientate obiect ;

-este folosita pt.a defini natura unui obiect ;

-este unitatea de baza pt.incapsulare ,incapsularea este cea care permite crearea unui obiect ;

-este creata prin utilizarea cuvantului cheie class ;

-o declarare a unei clase defineste un nou tip de data folosit pt.a declara obiecte de acel tip ;

-uneste cod si date clasa =date +cod;

Momentul aparitiei unui obiect (la declararea sa) se numeste instanta .

-o clasa este o abstractizare logica iar obiectul are o existenta fizica deci obiectul este o instanta a unei clase ;

-o functie membra a unei clase se numeste metoda;metodele pot sa aiba acces la orice element al clasei din care fac parte ;

-variabilele care sunt membre ale unei clase sunt numite variabile membre sau date membre ;

Un obiect este o entitate logica ce incapsuleaza date si cod ,codul fiind cel care manevreaza datele.Codul este cel care realizeza operatii care prelucreaza datele.

Definitia unei clase consta in doua parti :declaratia si implementarea .

Declaratia este o insiruire a elementelor componente ale unei clase (date si functii).

Implementarea este acea sectiune in care se implementeaza functiile declarate (adica se implementeaza prototipurile/se scrie codul functiilor ) .Fiind membre ale unui tip de date accesul la date se realizeaza prin intermediul operatorului de apartenenta " . "

Uzual ,partea de definire a unei clase se pune intr-un fisier de tip header ,ce va fi preluat cu #include " nume_fisier.h"de programatorii care dezvolta aplicatii folosind clase deja existente ;prototipurile descrise in definirea clasei sunt suficiente in faza de compilare ;partea de implementare unde se da codul executabil al fiecarei functii membre se pune in fisiere de tip .CPP si se poate prelua abia in faza de linkeditare ,deja compilata .

Datele si functiile unei clase pot fi grupate din punct de vedere al dreptului de acces in trei categorii demarcate prin etichetele cheie private , public si protected .

Domeniul private cuprinde date si functiile membre ce pot fi folosite doar de catre celelalte functii apartinand clasei respective .Eticheta private poate lipsi .

Domeniul public cuprinde datele si functiile membre ce sunt vazute prin intermediul obiectului si pot fi folosite sau apelate de catre oricare alte functii din cadrul programului adica sunt accesibile oricarei apelari exterioare.Cand nu apare eticheta public intreaga clasa este privata accesul asigurandu-se in exclusivitate prin interfata adica prin functiile de acces mentionate in clasa .

Domeniul protected similara cu private dar care da drepturi de acces functiilor membre ale claselor derivate din clasa de baza .

In comparatie cu clasele din punct de vedere al accesului ,structurile se considera entitati cu acces implicit public .

Functiile membre ale unei clase se impart in :

1.constructori responsabili cu crearea obiectelor ; initializarea datelor membre din obiect;

2.destructorul responsabil cu distrugerea obiectelor si eliberarea memoriei ocupate de acestea ;

3.functii de acces care mediteaza legatura obiectului cu exteriorul(adica au rolul de extragere a datelor si comunicare a lor prin interfata cu exteriorul clasei);

4.metode adica functii care introduc operatiile si prelucrarile specifice obiectului .

-o variabila de tip clasa poate stoca un set complet al datelor clasei respective .

-o instantiere a clase reprezinta un set concret de date adica o manifestare concreta a clasei o astfel de instanta poarta numele de obiect .

Un membru a clasei este calificat :

-prin operatorul de rezolutie :: in raport cu clasa careia apartine ;

-cu . sau -> in raport cu instantierile acesteia adica obiect sau pointer la obiect .


FUNCTII MEMBRE INLINE :

-pot fi implicit inline adica definite in interiorul clasei astfel apelul functiei este inlocuit pretutindeni cu codul intregii functii evitandu-se pierderea timpului pt.transmiterea parametrilor de apel pe stiva;implementarea se realizeaza o data cu declararea ;

-nu admit folosirea instructiunilor repetitive (bucle de orice tip , switch ) in cadrul lor, deoarece aceste functii sunt expandate de compilator in expresii macro deci trebuie cunoscut corpul functiei ,acest lucru nu se poate realiza in cazul utilizarii buclelor.

-sunt cele mai stabile (nemodificabile);

-definire explicita inline :

class persoana
{
private :
int varsta ;
public :
int spune_varsta( );
};
inline int persoana :: spune_varsta ( ) {return varsta ; } //definire explicita ,inline este cuvant cheie C++

CONSTRUCTORI

-Sunt metode care creaza noi instante ale clasei.

-Un constructor este o functie speciala care este membru a unei clase si are acelasi nume cu acea clasa ;

-Nu returneaza nici o valoare (nici macar de tip void )

-Nu poate fi virtual

-Nu poate fi mostenit de o alta clasa dar poate fi apelat de clasele derivate .

-In cadrul costructorului pot fi apelate alte functii membre sau nu.

-O clasa poate avea mai multi constructori prin supraincarcare (la declararea unei variabile de clasa / obiect constructorul este dedus dupa numarul si tipul parametrilor de apel ai constructorului);

-Se declara in domeniul public al clasei pentru a se autoriza accesul in folosirea lui ca metoda generala.

-Este util sa definim mai multi constructori pt.o clasa deoarece modurile de initializare a datelor membre sunt diverse :

-initializarea membrilor cu constante ex. persoana p1=persoana ("vasile",30,50000);

-initializarea din date elementare

-initializarea prin citire de la tastatura

-initializare prin citire din fisier

-initializare din datele unui alt obiect

-Apelul costructorului se produce in momentul declararii obiectului;

-Pt.un obiect este selectat totdeauna un singur constructor care este apelat o singura data ; nu se mai poate ulterior apelea alt constructor pt.respectivul obiect;

-initializeaza un obiect inaintea folosirii sale efective deci cand este creat;

- pot face operatie de alocare dinamica de memorie ;

- pot deschide fisiere ;

-Daca nu defineste explicit nici un constructor atunci constructorul implicit este definit automat de compilator si nu face nimic doar se foloseste pt. a genera obiecte ale clasei respective ;

-constructorul este singura functie membra care este vazuta in afara clasei fara a specifica un obiect sau pointer la obiect adica apelurile de forma p.f( ) sau pp->f( ) acest lucru se asigura prin faptul ca el poarta numele clasei si este deci si functie si tip in acelasi timp adica nu se pot utiliza pointeri catre constructori sau destructor ;

ex.

class persoana

{

int varsta ;

float salar;

char nume[20];

public:

persoana( ) {strcpy(nume,"ANONIM"); varsta=0;salariu=0;}

persoana ( char *n , int v , float s) {strcpy(nume,n);varsta=v;salariu=s;} //din date elementare

char *spune_nume( ){return nume;}

int spune_varsta ( ){ return varsta;}

};

-primul constructor nu are nici un parametru (persoana( )) si initializeaza datele membre cu valori constante ;un astfel de constructor (fara parametrii)se numeste constructor implicit ;

constructorul astfel definit in clasa persoana se apeleaza astfel :

persoana p1 ;

-persoana ( char *n , int v , float s) are trei parametrii si are ca scop initializarea datelor membre din date elementere ;

constructorul explicit astfel definit in clasa persoana se apeleaza astfel :

persoana p2("GIGI ",45,1000000);

Simpla definire a unui obiect (p1) determina apelul constructorului implicit ,in cazul obiectului p2 prin parametrii de apel s-a sugerat care constructor sa fie apelat.

Cei doi constructori ai clasei (cel implicit si cel din date elementare ) pot fi (nu e obligatoriu) combinati in unul singur care primeste parametri cu valori implicite :

persoana (char *n="ANONIM",int v=0 ,float s=0) : varsta(v) , salar(s) { strcpy(nume,n) ; }

Lista de initializatori este cea separata prin : de prototipul functiei .

void main ()

{

persoana p1 , p2("GIGI ",45,1000000);

cout<<p1.spune_nume( )<<p1.spune_varsta( );

cout <<p2.spune_nume ( )<<p2.spune_varsta( );

}

va afisa : ANONIM 0 GIGI 45

ex.:

persoana p("mircea ",52333); //apelul constructorului

persoana p1;

persoana p4=persoana( );

Constructorii pot fi :

-constructori impliciti ,fara argumente sau cu argumente implicite

-constructori de copiere cand primul argument este o referinta catre acelasi tip

Ex .de constructor cu argumente implicite :

class persoana {

char nume[40];

long int telefon ;

public:

persoana (char *n="nume",long t=909090);

};

persoana :: persoana (char *n,long t)

{

strcpy(nume,n); //copiaza sirul n in sirul nume

telefon =t ;

}


CONSTANTA ASOCIATA UNEI CLASE

O constanta asociata unei clase poarta numele clasei asociate .

Pt.clasa persoana o constanta apare sub forma persoana("VASILE",30,50000) si poate fi folosita la initializarea in bloc a unei variabile de clasa persoana astfel : persoana p3 =persoana ("VASILE", 30 ,50000);

astfel denumirea clasei apare de doua ori ,o data pt.obiect si o data pt.constanta de initializare .

Difera fundamental de declaratia: persoana p1("VASILE",30,50000); in care constructorul se apeleaza implicit prin definirea obiectului .

Faptul ca este implicat tot constructorul si in declararea constantei o dovedeste si ordinea constantelor de initializare care corespunde parametrilor de apel al constructorului si nu corespunde odinii campurilor din definitia clasei.

ex.

persoana p1("POP",28,1000);

persoana p2=p1 , p3;

p3=persoana (p1.spune_nume ( ) ,p2.spune_varsta( ),500000);


COSTRUCTOR DE COPIERE

-pt.initializarea obiectelor din altele deja existente (persoana ob2=ob1;)

-pt.transmiterea obiectelor prin valoare in si din functii (f(ob1) sau return ob; )

-are ca prim argument (parametru) o referinta catre clasa al carui constructor este;

-fiecare clasa dispune si de un constructor de copiere implicit pus de compilator care realizeaza copierea obiectului sursa in obiect destinatie bit cu bit

-sau explicit dat de programator .

-un costructor de copiere lucreaza cu doua obiecte unul recunoscut implicit printr-un pointer (this ) si unul explicit primit ca parametru prin referinta .

-constructorul de copiere face o copie controlata a datelor preluate dintr-un obiect existent .

#include <iostream.h>

class cls {

public :

int x;

cls(int a=0):x(a) {cout<<"CONSTRUCTOR DE CLASA ";}

cls(cls & c){cout<<"COSTRUCTOR DE COPIERE ";} //nu face nimic nu are instructiuni in bloc

};

void main ()

{

cls c1(1),c2=c1;

cout<<c1.x<<endl; //va afisa 1

cout<<c2.x<<endl; //nu se initializeaza campul x pt.ca nu face constructorul copierea

}

sau

#include <iostream.h>

class cls {

public :

int x;

cls(int a=0):x(a) {cout<<"CONSTRUCTOR DE CLASA ";}

// cls(cls & c){cout<<"COSTRUCTOR DE COPIERE ";} //s-a anulat

};

void main ()

{

cls c1(1),c2=c1;

cout<<c1.x<<endl; //va afisa 1

cout<<c2.x<<endl; //va afisa 1 deci campul x este initializat de c.de copiere implicit pus de compilator

}


OBIECTE CU EXTENSII IN MEMORIA DINAMICA

Este posibila definirea unor clase ale caror elemente sa fie dimensionate dinamic pt.folosirea eficienta a memoriei .

ex.char nume[20] ocupa 20 baiti ;

char *pnume ocupa 2 baiti si va pointa spre o zona alocata dinamic in functie de lungimea numelui fiecarei persoane.

Clasele cu membri alocati dinamic se mai numesc si clase cu membrii pointeri.

Practic in acest caz un obiect va ocupa doua categorii de memorie :

-una alocata si eliberata implicit la definirea obiectului ,respectiv la terminarea duratei lui de viata ;

-una alocata si elibarata explicit prin codul pus de programator in constructor si destructor .

CONSTRUCTORUL DE COPIERE SI OPERATORUL DE ATRIBUIRE IN SITUATIA OBIECTELOR CU EXTENSII IN MEMORIA DINAMICA

1.constructorul de copiere copiaza obiectul sursa intr-o zona neinitializata in care isi construieste un obiect nou .

Costructorul de copiere este invocat :

a)la crearea de obiecte cu initializare (atentie nu atribuire )pornind de la un obiect care exista :

cazul persoana p3=p1;

b)la apelul unei functii care lucreaza cu obiecte transferate prin valoare cand este nevoie de crearea unei copii a obiectului pe stiva :cazul f(p1)

c)returnarea dintr-o functie a unui obiect prin valoare cazul return p1;

2.operatorul de atribuire operator=( ) Operatorul de atribuire lucreaza cu doua obiecte deja existente sursa si destinatie avand sarcina de a copia informatiile dintr-o zona in alta .

Aceste doua functii sunt prezente in orice clasa (sunt puse automat de compilator daca programatorul omite scrierea lor ).

Ambele fac copieri de obiecte dar deosebirile sunt esentiale .

Pt.un obiect cu un membru pointer spre o zona alocata dinamic programatorul va furniza :

a)constructori adecvati de clasa care sa aloce extensia si sa incarce pointerul prin care o gestioneaza

b)constructor de copiere care sa aloce extensia pt.noul obiect ,sa incarce pointerul prin care o gestioneaza si sa initializeze extensia copiind extensia din obiectul de initializare ,

c)destructor de clasa care sa dezaloce extensia adresata prin pointerul membru ;

d)operator de atribuire care sa dezaloce extensia adresata prin pointerul membru al obiectului destinatie ,s-o realoce si sa incarce conform dimensiunii si continutului celei din obiectul sursa.

Pentru a usura depanarea programelor si pt. a beneficia de verificari competente facute de compilator este bine ca functiile ce lucreaza cu obiecte fara a le modifica sa fie marcate cu const .Spre exemplu un constructor de copiere este mai bine declarat sub forma :

persoana (const persoana & p);

atentionand ca obiectul sursa nu este alterat prin copiere , pentru initializarea altui obiect .


DESTRUCTOR

-Este declarat in zona public: nu in alta zona ;

-Elimina un obiect din memorie sau poate inchide un fisier .

-Dezactiveaza toate functiile unui obiect acesta fiind astfel distrus .

-Are acelasi nume cu clasa din care face parte si este precedat de caracterul tilda ~ de fapt se neaga un constructor prin intermediul operatorului de negatie ~

-In mod uzual sunt utilizati in cadrul obiectelor ai caror constructori realizeaza alocari dinamice de memorie caz in care destructorul are cod explicit .

Ex.

persoana ::~persoana ( )

{

delete [ ] pm;

}

In rest nu contine cod executabil .

-Ordinea de apel al destructorului este inversa ordini de apelare a constructorilor.

-Este apelat implicit la iesirea din blocul in care a fost declarat obiectul definit de o clasa .

-Nu poate fi mostenit de o alta clasa dar poate fi apelat de clasele derivate .

-Cand lipseste este generat automat de catre compilator in sectiunea public.

- o clasa poate avea un singur destructor (nu mai multi) deci este unic ;

- destructorii nu pot avea parametrii de apel ;

- nu returneaza nimic ,nici macar void .

-constructorul este apelat de fiecare data cand este intalnita instructiunea de declarare a unui obiect ;

-cand doua sau mai multe obiecte sunt declarate in aceeasi instructiune constructorii sunt apelati in ordinea in care sunt ele intalnite de la stanga la dreapta si de sus in jos ;

-functiile destructor pentru obiectele locale sunt executate in ordinea inversa fata de cele constructor ;

-functiile constructor pentru obiectele globale sunt executate inaintea lui main( )

-obiectele locale sunt create cand se intra in blocul lor si distruse cand blocul este parasit

-obiectele globale sunt distruse (se apeleaza destructorul )cand se termina programul adica dupa ce se incheie main() destructorul fiind apelat in ordine inversa .

ex.

#include<iostream.h>

class apel{

int nr;

public:

apel(int a) ;

~apel();

}global_ob1(1),global_ob2(2) ; //obiecte globale

apel :: apel(int a)

{

cout<<"initializare obiect "<<a<<endl;

nr=a;

}

apel ::~apel()

{

cout<<"obiect distrus"<<nr<<endl;

}

apel global_ob3(3); //obiect global

void main ()

{

//obiecte locale

apel local_ob4(4);

apel local_ob5(5);

}

prg.are urm.iesire :

initializare obiect 1

initializare obiect 2

initializare obiect 3

initializare obiect 4

initializare obiect 5

obiect distrus5

obiect distrus4

obiect distrus3

obiect distrus2

obiect distrus1


POINTER THIS

-Functiile friend nu sunt membrii clasei de aceea nu au pointer this .

-Functiile membre static (medodele statice) nu au pointer this .

-spre deosebire de pointerii utilizati in mod uzual pointerul this realizeaza uniunea dintre membrii unei clase si functiile care actioneaza asupra acestora ( functiile membre).

-cand este apelata o functie membru va primi pe langa parametrii de apel expliciti si un parametru implicit care este adresa obiectului vizat ,adica a obiectului asupra caruia se efectueaza prelucrarile.Aceasta adresa desi transparenta (nu se vede)exista memorata intr-un pointer numit this (cuvant cheie).

-This este transmis ca prim parametru de apel a metodei (prim argument)care este un pointer catre obiectul care cheama functia.

ex.

Se defineste metoda adresa( ) in clasa persoana care va afisa pointerul this :

void persoana :: adresa( )

{cout<<"Adresa fizica a obiectului este :"<<this ; }

Datele membre sunt referite direct cand se definesc functii membre ,de ex.metoda spune_varsta refera direct membrul varsta :

int persoana :: spune_varsta(){return varsta;}

dar de fapt referirea se face prin intermediul pointerului this .

Scris explicit apare astfel :

int persoana ::spune _varsta( ) {return this -> varsta ;}

ex.

#include <iostream.h>

class putere {

double b;

int e;

double val;

public:

putere (double baza,int exp);

double da_putere(){return val;}

};

putere ::putere (double baza,int exp)

{

b=baza;

e=exp;

val=1;

if(exp==0) return ;

for( ;exp>0;exp--) val=val*b;

}

main ()

{

putere x(4.0,2),y(2.5,1),z(5.7,0);

cout<<x.da_putere()<<"\n";

cout<<y.da_putere()<<"\n";

cout<<z.da_putere()<<"\n";

return 0;

}

explicatie : la membrii clasei putere se poate capata acces direct din cadrul unei functii membru fara nici un specificator de aceea instructiunea b=baza din interiorul functiei putere( ) comanda ca valoarea continuta in baza sa fie atribuita unei copii a lui b asociata obiectului care a genarat apelarea .

b=baza ; //identic cu this->b=baza ;

e=exp; //identic cu this->e=exp;

val=1; //identic cu this ->val=1;

Pointerul this indica catre obiectul care a apelat functia putere( );

Astfel this->b se refera la copia b pt.acel obiect .

De ex.daca putere( ) este apelata de obiectul x(4.0 , 2) atunci this->b indica spre obiectul x .


FUNCTII DE ACCES

-returneaza valoarea unei date membre private get_xxx( ) adica nu o modifica ci o comunica in exterior.

-modifica valoarea unei date membre private set_xxx ( )

ex.

void persoana ::set_varsta(int k) {varsta=k ;} //va seta varsta unei persoane

Modificarea unor date private se poate realiza numai prin functii membre.


POINTERI LA OBIECTE

-Pointerul la obiect este o variabila care contine adresa unei obiect .

-Deci se pot manevra si obiecte prin intermediul adreselor lor.

-declararea unui pointer la obiect nu declanseaza executia vreunui constructor al clasei ,deoarece se aloca memorie doar pentru o variabila capabila sa stocheze o adresa ;

ex.

persoana p, *pp;

-incarcarea unui pointer se poate face pornind de la adresa unui obiect deja definit

ex.

pp=&p;

-accesarea membrilor (publici ) se face cu ajutorul operatrului -> ca la structuri :

ex.

pp->spune_varsta( ) ; //apelul metodei spune_varsta( )

pp->nume ; //accesarea membrului nume


OPERATORUL NEW

Pentru gestioanarea memoriei in C++, avand de manevrat obiecte avem la dispozitie doi operatori asemanatori functiilor de biblioteca din C malloc( ) si free( ) dar mult mai evoluati ca domeniu de actiune new si delete .

Diferente intre malloc ( ) si new :

-new poate produce apelul unei constructor si aloca memorie

-malloc ( ) nu poate apela un constructor poate doar aloca memorie

-new stie cata memorie trebuie alocata oricarui tip de variabila ,functiei malloc( ) trebuind sa i se specifice aceasta dimensiune

ex.

persoana *pp=new persoana ; //aloca zona de memorie capabila sa stocheze un obiect persoana ,adresa zonei

este stocata in variabila pointer pp si se executa constructorul implicit al clasei persoana

persoana *pp=new persoana ("Liviu ",9,250000); //se poate apela si constructorul explicit

Operatorul new poate fi folosit si in declararea de masive :

int *p=new int[10];

sau masive de obiecte :

punct *a=new punct[10];

OPERATORUL DELETE

-este analogul functiei free ( ) din C

-are ca scop eliberarea memoriei ocupate cu ajutorul operatorului new .

Asa cum new este utilizat in general in interiorul constructorilor tot asa si delete isi are locul in cadrul destructorului.Se va apela destructorul obiectului si apoi se va elibera memoria alocata obiectului.

-deosebirea intre delete si free ( ) este aceea ca free( ) nu determina apelul destructorului .

-delete poate elibera selectiv spatiul alocat de new astfel:

ex.

int *m=new int[10];

delete m; //det. eliberarea spatiului ocupat de un singur intreg cel de la indexul m[0],restul locatiilor de memorie ramanand ocupate

Pentru a elibera complet spatiul alocat :

int *m=new int[10];

delete [ ] m;


MASIVE DE OBIECTE

ex.de initializare masiv (tablou de obiecte):

persoana grup[ ]={

persoana ("Adam D.",35,75000), /*se creaza o lista de instantiere avand drept elemente

persoana (), constructori ai obiectului */

persoana ("Ion ",26,75000)

};

-dimensiunea este dedusa automat de compilator din lista de initializatori ;

-sau poate fi data explicit

-constructorul clasei va fi apelat repetat pentru fiecare element in parte .

-o functie ca acces la elementele masivului va trebui sa fie corect specificata precizandu-se indexul elementului :

cout<<grup[1].spune_varsta( );

ex.

punct triunghi[3]={{0,0},{100,90},{50,80}}; //tablou initializat in momentul declararii sale

ex.

class punct {

public:

int x,y;

punct (int x1,int y1) {x=x1;y=y1;} //constructori de clasa

punct(int x1) {x=x1; y=x1;}

};

main ( )

{

punct triunghi[3]={

punct(1,2),

punct(30,90), /*se creaza o lista de instantiere avand drept elemente

punct(20,20) constructori ai obiectului */

};

return 0;

}

sau

punct triunghi[3]={

1, //se apeleaza constructorul cu un parametru

punct(2,1), //se apeleaza constructorul cu doi parametrii

8 //se apeleaza constructorul cu un parametru

};

Un caz aparte il constituie constructorul implicit ,acesta neavand parametrii .O modalitate de a instantia un tablou de obiecte avand numai constructor implicit este :

punct triunghi [3] ;

Instantierile partiale ale unui tablou de obiecte sunt posibile numai in cazul prezentei constructorului implicit.

ex.

class punct {

public:

int x,y;

punct (int x1,int y1) {x=x1;y=y1;} //constructori de clasa

punct(int x1) {x=x1; y=x1;}

punct ( ) {x=0;y=0;} //constructor de clasa implicit

//sau asa punct(int a=0,int b=0 ) {x=a;y=b;} //un constructor cu argumente implicite este un constructor implicit

};

main ( )

{

punct triunghi[3]={1 , punct(30,90) }; //instantiere partiala

punct p[4];

return 0;

}


TRANSFERUL OBIECTELOR IN / DIN FUNCTII

Ca si pentru tipurile fundamentale compilatorul aloca in anumite situatii spatiu temporar pe stiva .Un exemplu concludent il reprezinta transferul si returnarea unui obiect in /din functii .

Obiectele pot fi transferate :

1.prin valoare

2.prin referinta

3.prin adresa

De crearea obiectelor temporare pe stiva necesare transferului este responsabil construtorul de copiere nu constructorul de clasa .

Constructorul de copiere primeste ca parametru de intrare prin referinta un obiect al clasei pentru a-l folosi la initializarea altui obiect.

1.LA TRANSFERUL PRIN VALOARE constructorul de clasa si cel de copiere se fiecare cate o data ,destructorul de doua ori ,deci constructorul de copiere creaza si initializeaza pe stiva un obiect temporar.

ex.

#include<iostream.h>

class cls {

public:

cls(){cout<<"constructor "<<endl;}

cls(cls &c) {cout<<"constructor de copiere "<<endl;}

};

int f(cls c){return 10;}

void main ()

{

cls c;

cout<<f(c); //transferul are loc prin valoare afiseaza 10

}

va afisa : constructor

constructor de copiere

10

2.LA TRANSFERUL PRIN REFERINTA constructorul de clasa se apeleaza o data iar constructorul de copiere nici o data ,destructorul o data .

ex.

#include<iostream.h>

class cls {

public:

cls(){cout<<"constructor "<<endl;}

cls(cls &c) {cout<<"constructor de copiere "<<endl;}

};

int f(cls &c){return 10;}

void main ()

{

cls c;

cout<<f(c); //transferul are loc prin referinta afiseaza 10

}

afiseaza :constructor 10

3.LA TRANSFERUL PRIN ADRESA nu mai este necesar de obiecte temporare pe stiva .


CLASE INCLUSE

-determina compunerea claselor si implicit lucrul cu obiecte continute in alte obiecte

-compunerea este o a doua modalitate de reutilizare a codului prima fiind mostenirea

-declaratia clasei copil se poate face in interiorul clasei persoana dar declaratia ramane cunoscuta doar la nivel acestei clase neputand produce instantieri copil (obiecte de tip copil ) in afara clasei persoana

-se mentioneaza de fiecare data si clasa persoana ca si cum clasa inclusa(interioara )se numeste persoana::copil

-constructorii clasei interioare primesc la intrare adresa unui obiect persoana adica de tipul clasei exterioare acesta fiind singurul mod de a lega obiectele interioare cand se definesc in afara clasei care le include adica s-a folosit persoana::copil pentru a defini obiecte de tip copil in afara clasei persoana .

-prin includerea unei clase in alta clasa implementam si o relatie ierarhica intre doua clase diferite respectiv intre obiectele acestora

-in tehnologia client-server clasa exterioara joaca rolul de clasa client iar cea interiora de clasa server de ex.o clasa fisier poate ingloba o clasa index care permite autoindexarea la scrierea obiectelor in fisier ,ex.clasele pt.structuri autoreferite (lista,stiva,coada etc)contin clase iterator incluse care sa permita descrierea unitara a algoritmilor ce presupun traversarea structurilor;

-includerea claselor nu presupune si acordarea unor drepturi de acces speciale clasei exterioare ex.functiile din clasa exteriora nu poate apela zona privata a clasei copil valabil si invers adica o functie din clasa copil nu poate accesa date private din clasa persoana ;conlucrarea intre se face numai prin functiile membre specializate ale fiecarei clase.ex.numele unui copil nu ar putea fi recompus din prenumele sau atasat numelui tatalui daca numele nu ar aparea public

-datorita mecanismului de mostenire clasele incluse sunt mai rar folosite .

#include<iostream.h>

#include<string.h>

class persoana {

public:

int varsta ;

char nume[20];

float salar;

class copil {

public:

char prenume[10];

int varsta ;

persoana *parinte;

copil(persoana *n=NULL,char pren[10]="PUIU",int v=0) :varsta(v) ,parinte(n){strcpy(prenume,pren);}

char *spune_nume();

int spune_varsta(){return varsta ;}

copil(copil &c) {cout<<"constructor de copiere"<<endl;}

} c[5]; //fiecare obiect persoana va avea un vector de maxim 5 obiecte de tip copil

persoana(char n[20]="ANONIM",int v=0,float s=0): varsta(v),salar(s){strcpy(nume,n);}

int spune_varsta(){return varsta ;} //nu poate fi aplelata pt.clasa copil

char *spune_n() {return nume;}

};

char *persoana::copil::spune_nume()

{

static char nume_pren[10];

strcpy(nume_pren,strtok(parinte->nume," "));//ia sirul de caractere dinaintea spatiului liber

strcat(nume_pren," "); //pune spatiu intre popescu viorel

strcat(nume_pren,prenume);

return nume_pren;

}

int f(persoana p) {return p.varsta+10;}//transferul are loc prin valoare

void main ()

{

persoana p1("popescu ion",29,1000000);

cout<<p1.spune_n()<<p1.spune_varsta()<<endl;

persoana p2("vasilescu ionel",22,200000);

cout<<p2.spune_n()<<p2.spune_varsta()<<endl;

p1.c[0]=persoana ::copil(&p1,"viorel",10); //apel constructor explicit copil pt. initializare cu constante

p1.c[1]=persoana::copil(&p1,"alina",15); //primeste adresa unui obiect persoana la initializare

cout<<"MA CHEAMA "<<p1.c[0].spune_nume()<<" "<<p1.c[0].spune_varsta()<<endl;

cout<<"MA CHEAMA "<<p1.c[1].spune_nume()<<" "<<p1.c[1].spune_varsta()<<endl;

p2.c[0]=persoana ::copil(&p2,"dan",5);

cout<<"MA CHEAMA "<<p2.c[0].spune_nume()<<" "<<p2.c[0].spune_varsta()<<endl;

int c=f(p1); //este apelat constructorul de copiere de 5 ori

cout<<c;

}

va afisa :

popescu ion 29

vasilescu ionel 22

MA CHEAMA popescu viorel 10

MA CHEAMA popescu alina 15

MA CHEAMA vasilescu dan 5

constructor de copiere

constructor de copiere

constructor de copiere

constructor de copiere

constructor de copiere

39

-clasele incluse sunt asemanatoare cu includerea de structuri in cadrul structurilor ; structurile se considera entitati cu acces implicit public .

ex

#include<iostream.h>

struct punct

{

int x,y;

void incarc_punct(int xi,int yi) {x=xi;y=yi;}

};

struct cerc{

punct centru; //reutilizare cod prin compunere

int raza ;

void incarc_raza(int r) {raza=r;}

};

void main()

{

cerc c ;

int a=10 ;

c.incarc_raza(a);

cout<<a<<endl;

int b=20;

c.centru.incarc_punct(a,b);

cout<<a<<" "<<b;

}

va afisa : 10 10 20

-ex.demonstreaza multitudinea formelor de adresare a unui membru dintr-o clasa inclusa intr-o alta clasa

#include<iostream.h>

struct persoana {

char nume[20];

struct copil{

char prenume[10];

int varsta;

} c[3];

}p1,*pp;

void main ()

{

pp=&p1;

p1.c[0].varsta=5;

p1.c[1].varsta=10;

p1.c[2].varsta=15;

cout<<pp->c->varsta<<endl; //afisa 5

cout<<pp->c[1].varsta<<endl; //afisa 10

cout<<(pp->c+2)->varsta<<endl; //va afisa 15 ;+2 indica de la al catelea index sa afiseze

cout <<((*pp).c)->varsta<<endl; // va afisa 5

cout<<(*pp).c[1].varsta<<endl; //va afisa 10

cout<<(*pp).c->varsta<<endl; //va afisa 5

}

ex.

#include<iostream.h>

#include<string.h>

class copil {

public :

int varsta ; //pt.apelul p1.c.varsta nu se poate declara in zona private nu ar avea acces

char prenume[20];

copil(int v=1,char *pren="puiu") : varsta(v) {strcpy(prenume,pren);}

};

class persoana{

int varsta ;

public:

copil c;

persoana(int v1=18,int v2=3,char pren[] ="puiu") : varsta(v1),c(v2,pren){}

};

void main ()

{

persoana p1(30,5,"sandu");

cout<<p1.c.prenume<<"are"<<p1.c.varsta<<"ani";

}

programul afiseaza : sandu are 5 ani


OPERATORUL DE REZOLUTIE ::

-este folosit la asocierea unui nume de clasa cu un nume de membru pt.a spune compilatorului carei clase apartine acel membru

-mai multe clase diferite pot folosi acelasi nume de functie ,compilatorul stie care functie apartine fiecarei clase datorita operatorului de rezolutie (sau numit si op.de specificare a domeniului);

ex.

int n=1; //variabila globala este inaintea lui main( )

void main( )

{

int n=2; //variabila locala este intr-un bloc de cod

afiseaza(n); // afiseaza 2, valoarea variabilei locale n

afiseaza(::n); // afiseaza 1,valoarea variabilei globale n

}

 


Proiect realizat de MARTON (POP) CLAUDIA an IV Ianuarie 2005