Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
AccessAdobe photoshopAlgoritmiAutocadBaze de dateCC sharp
CalculatoareCorel drawDot netExcelFox proFrontpageHardware
HtmlInternetJavaLinuxMatlabMs dosPascal
PhpPower pointRetele calculatoareSqlTutorialsWebdesignWindows
WordXml


C+CLASE IMBRICATE. OBIECTE SI FUNCTII

c



+ Font mai mare | - Font mai mic



CLASE IMBRICATE. OBIECTE SI FUNCTII

Atunci, cand o clasa se defineste in cadrul unei alte clase, se spune ca sunt clase imbricate.



O clasa imbricata este valida doar in interiorul clasei ce o contine. Avand in vedere posibilitatile oferite prin mecanismul de mostenire, astfel de clase se utilizeaza mai rar.

Exemplu:

#include <iostream.h>

class vector

o,v;

public:

void in_vect(float x1,float y1,float x2,float y2)

void afis();

};

void vector::punct::in_punct(float x1,float y1)

void vector::punct::afis()

void vector::afis()

void main()

O clasa poate contine ca membri, instantieri ale altor clase (obiecte imbricate) cu o remarca asupra faptului, ca nu se permit initializari in cadrul declararii acestor clase.

Exista o conventie asupra apelului constructorilor obiectelor membre.

Sa consideram urmatoarea situatie: A este o clasa care contine un obiect imbricat de tip 'TB' care, la randul sau, contine un membru M de tip pointer. Sa presupunem ca prin constructorul clasei TB se aloca dinamic o zona de memorie la care va pointa M.

Daca constructorul TB nu a fost apelat, nu se accepta ca prin constructorul A sa se initializeze zona la care pointeaza M, pentru ca:

a)      pointerul M va lua o valoare aleatoare;

b)      se pot distruge informatii din memorie.

In C++ exista un mecanism convenabil in acest sens.

Sa consideram clasa A care contine ca membri, obiecte ale altor clase A1,A2,..,An.

Pot fi intalnite urmatoarele situatii:

clasele Ak nu au constructori (k=1,,n) (in acest caz, nu vor exista deosebiri intre constructorii clasei A si un constructor al unei clase ce nu contine obiecte membre imbricate);

clasele Ak (k=1,,n) nu au un constructor implicit si nici un constructor cu parametri cu valori implicite (intr-o astfel de situatie este obligatoriu a se specifica explicit numele fiecarui obiect urmat de lista parametrilor actuali):

iden_obiect(lista_param_actuali)

clasele Ak (k=1,,n) au un constructor implicit sau unul cu toti parametrii cu valori implicite (se poate proceda ca in primul caz, apelandu-se implicit constructorii respectivi, sau ca in a doua situatie, specificandu-se explicit doar parametrii solicitati).

Intotdeauna apelul constructorilor obiectelor imbricate se va efectua inainte de executarea constructorilor clasei A. Pentru a preciza ordinea de apelare a constructorilor obiectelor imbricate este necesar a se mentiona aceasta in definitia constructorului clasei A si nu in declaratia sa.

Unele aspecte cu privire la utilizarea destructorilor in clasele imbricate:

Sa presupunem ca avem urmatoarea situatie:

class U

ob;

#n acest caz, apelul destructorilor pentru obiectele ob1 si ob2 se va face dupa executia '~U( )'.

Daca presupunem ca avem o adresare indirecta de forma 'pointer la obiect imbricat', in loc de obiecte imbricate, atunci va fi necesar atat alocarea dinamica cat si eliberarea explicita a zonei de memorie necesara pentru obiectele spre care vor pointa membrii respectivi. Aceste operatii se executa prin constructorul / destructorul clasei care contine obiectele imbricate.

O atentie sporita trebuie acordata mecanismului de copiere bit cu bit a obiectelor. Pot aparea erori nu la copiere, ci la apelul destructorului care este obligat sa elibereze de mai multe ori aceeasi zona de memorie.

Exemplu:

class punct

punct(int a, int b)

~punct( ); };

class vector

;

class triunghi

vector::vector(int a, int b):vf(a,b)

vector::vector(int a1,int b1,int a2,int b2):og(a1,b1),vf(a2,b2)

triunghi:: triunghi(int a1, int b1, int a2, int b2, int a3, int b3)

Exista deosebiri sintactice / semantice intre acest exemplu si ultimul program din aL5s ?

Cand o clasa este declarata intr-o functie, ea este cunoscuta doar in interiorul acelei functii si nu in exteriorul ei. O astfel de clasa se numeste clasa locala. Daca se utilizeaza o astfel de clasa, trebuie sa tinem cont de urmatoarele:

a)      toate functiile membre trebuie definite in interiorul declaratiei clasei;

b)      clasa locala nu are acces la variabilele locale ale functiei in care ea este declarata (cu exceptia variabilelor locale declarate static in interiorul functiei);

c)      intr-o clasa locala nu se poate declara nici o variabila de tip static, de aceea astfel de clase sunt mai putin uzuale in C++.

Exemplu:

# include <iostream.h>

void gama( );

main( )

void gama( )

int af( )

}ob;

ob.scrie(30);

cout<<ob.af( );

Transmiterea obiectelor catre functii se realizeaza asemanator cu transmiterea oricarui alt tip de parametru. Se utilizeaza mecanismul 'apel prin valoare', adica prin copiere. Efectuarea unei copii inseamna crearea unui obiect nou. Se pune intrebarea, daca efectuarea unei copii, solicita apelul unui constructor al obiectului la crearea copiei sale si daca se executa destructorul la distrugerea copiei respective.

Sa urmarim urmatoarea secventa:

class A

int revin( )

A::A(int p)

A::~A( )

// distrugere

void g(A ob);

void main( )

void g(A ob)

Analizand iesirea acestui program, se observa ca se apeleaza de doua ori functia destructor si o singura data functia constructor. Conform iesirii, functia constructor nu este apelata, cand copia lui 'ob_1' din main() este transmisa lui 'ob' din g( ). Cand se transmite un obiect catre o functie, se vrea starea curenta a obiectului. Daca ar fi apelat constructorul pentru a crea copia obiectului respectiv, s-ar produce initializarea noului obiect creat si ar putea fi modificat. De aceea, constructorul nu va fi apelat la crearea copiei. Copia, la fel ca o variabila locala obisnuita, se poate distruge la finele executiei functiei. Copia, care se creaza la nivel de bit, poate realiza diverse operatii, ceea ce impune apelul destructorului pentru inlaturarea sa.



O functie poate returna un obiect in punctul apelant.

Exemplu:

................

class A

int afis( )

};

A g( );

// returneaza obiect de tipul A

void main( )

A g( )

Cand un obiect este returnat de o functie, este creat automat un obiect temporar, care contine valoarea returnata. Acesta este obiectul care este returnat de functie. Dupa returnare, obiectul respectiv este distrus. Distrugerea obiectului temporar poate avea si efecte negative. Daca obiectul, care a fost returnat, are un destructor care elibereaza zona de memorie alocata dinamic, aceea memorie va fi eliberata, chiar daca obiectul, care primeste valoarea returnata, inca o mai foloseste Prevenirea unei astfel de situatii se face cu ajutorul supraincarcarii avezi L.10s operatorului de atribuire si definirea unui constructor de copiere.

Daca doua obiecte sunt de acelasi tip, se poate realiza o atribuire intre ele. Aceasta inseamna ca datele obiectului din membru drept al operatorului de atribuire vor fi copiate, in mod corespunzator, in datele obiectului din membru stang.

Exemplu;

class A

void main( )

}

Aplicatie.

Sa se calculeze aria unor figuri geometrice plane.

#include<iostream.h>

#include<conio.h>

#include<stdlib.h>

#include<math.h>

#define EROARE -1

#define CERC 0

#define PATRAT 1

#define DREPTUNGHI 2

#define TRIUNGHI 3

#define PI 3.141

class GEOM

fig;

public:

int tip;

GEOM();

double aria(GEOM*p);

int cit_fig(GEOM*p);

};

double GEOM::aria(GEOM*p)

default:return 0;

}

}

int GEOM:: cit_fig(GEOM*p)

case PATRAT:for(;;)

case DREPTUNGHI:for(;;)

case TRIUNGHI:for(;;)

default:return 0;

}

void main(void)

case 'D':

case 'P':

case 'T':

default:cout<<'S-a tastat alt caracter!';

}

if(f.tip!=EROARE)break;}

if(f.cit_fig(&f)==0)exit (1);

if(f.aria(&f)==0)exit(1);

cout<<'ARIA FIGURII:n'<<f.aria(&f);

}

Ce se intampla cu constructorii si destructorii in aceasta implementare? Este o eroare? De ce?

Sa se realizeze o noua implementare in C++ pentru o astfel de aplicatie care sa contina    clase imbricate.

Aplicatie:

Sa se selecteze un anumit numar de elemente dintr-un sir de numere intregi, sa se ordoneze subsirul extras si sa se calculeze norma acestuia din urma. Utilizati o clasa locala in functia de afisare a normei.

#include<iostream.h>

#include<conio.h>

#include<math.h>

#define MAX 50

void afis(double);

void sort(int a[],int m)

p++;}

}

}

void suma_patrat(int a[],int m)

void afis(double t)

void af(double t)

}v;

v.af(t);

}

void main(void)

cout<<'Numar elemente sortate:';

cin>>m;

sort(a,m);

cout<<'Elem.sortate:n';

for(i=1;i<m+1;i++)suma_patrat(a,m);}

Tema propusa

Sa se scrie un program, folosind clase imbricate, pentru conversia numerelor naturale

nenule, din baza zece in bazele 2,8,16 (eventual si alte baze).

Sa se scrie programe in care sa se puna in evidenta modul de transmitere a unor obiecte catre functii, facandu-se o analiza corespunzatoare asupra apelului functiilor constructor si destructor.

Folosind clase locale, sa se scrie un program care sa reflecte situatia la o sesiune de examene a unei grupe de studenti.

Realizati un program pentru parcurgerea unui arbore in care nodurile sa fie de tip class.

Sa se scrie un program pentru rezolvarea ecuatiei de gradul doi cu coeficienti complecsi.




Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 1287
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved