Sunteți pe pagina 1din 47

Subiect T1.

Clasa in OOP

O clasă defineşte un tip abstract de date, asta însemnând faptul că un astfel de tip deţine atât mulţimea
de date, cât şi setul de operaţii ce se efectuează cu acele date. Mulţimea de date poartă numele de date
membru, iar, mulţimea de operaţii, poartă numele de funcţii membru sau metode.

Acestea, în construcţia unei clase, sunt supuse influenţei a 3 specificatori de protecţie, şi anume:

 private – care este cel implicit, şi inhibă vizibilitatea datelor şi metodelor ce se află sub incidenţa
sa în afara clasei de definire
 public – vizibilitate date şi metode de oriunde din interiorul clasei şi din afara sa
 protected – vizibilitate date şi metode în clasa respectivă şi ierarhii din clasa respectivă.

Forma sintactică a unei clase este următoarea:

class nume_clasa
{
[private:]
date_membru;
funcţii_membru (metode);
protected:
date_membru;
funcţii_membru (metode);
public:
date_membru;
funcţii_membru (metode);
};
Definirea unei metode se poate face în interiorul clasei, în acest caz, funcţia fiind catalogată ca una in-
line (asta înseamnă că compilatorul înlocuieşte automat apelul prin codul efectiv al funcţiei, realizare
virtuală), sau, în afara clasei, după următoarea sintaxă:

tip_rezultat_functie nume_clasa::nume_metoda(linie_parametri_formali)
{
corp_propriu_funcţie;
[return …;]
}

In afara metodelor, intr-o clasa pot fi definite si funcţii prieten. Acestea au proprietatea că vor fi definite
şi apelate precum funcţiile obişnuite, dar, prin faptul că îşi găsesc antetul în interiorul unei clase,
înseamnă că pot utiliza toate datele acesteia, indiferent de forma de protecţie.

Marea diferenţă între o metodă şi o funcţie prieten constă în apel, şi anume, metoda se apelează printr-
un obiect, iar, funcţia prieten, nu, asemeni unei funcţii obişnuite, astfel încât, dacă avem nevoie de un
obiect, acesta trebuie transmis prin linia de parametri.

Exemplificare: se va scrie o clasă pentru citirea şi afişarea unui număr complex.

#include<iostream>
using namespace std;

class complex
{
private:
double a,b;
public:
void atribuire(int i=0, int j=1) /*functie de atribuire, definita fiind ca functie
in-line, ptr. simplul motiv ca ea a fost scrisa in interiorul clasei*/
{
a=i; b=j;
}
double& ret_re(); /*functie care va returna partea reala din numarul complex,
functia alegem sa intoarca o referinta, pentru a putea fi apelata si din partea stanga,
ea nu este definita in interiorul clasei, ci va fi definita in afara acesteia*/
double& ret_im(); //functie ce returneaza partea imaginara
void citire(); //functie pentru citirea unui numar complex
friend void afisare(complex, char*); /*functie pentru afisarea unui numar
complex, functia de fata este una prieten*/
};

inline double& complex::ret_re() /*prin faptul ca pus cuvantul inline, functia, chiar
daca e definita in afara clasei, este prelucrata ca fiind functie in-line*/
{
return a;
}

inline double& complex::ret_im()


{
return b;
}

void complex::citire()
{
cout<<"\tpartea reala: ";
cin>>a;
cout<<"\tpartea imaginara: ";
cin>>b;
}

void afisare(complex z, char* s)


{
cout<<"Nr. complex "<<s<<" este: "<<z.a;
if(z.b>=0)
cout<<'+'<<z.b<<"*i\n";
else
cout<<z.b<<"*i\n";
}

int main()
{
complex z1,z2,z3;

cout<<"Citim nr. complex z1 prin functia de atribuire\n";


z1.atribuire(3,-4); /*z1, in acest caz, se cheama obiect curent, pentru ca el
este cel care apeleaza functia*/

cout<<"Citim nr. complex z2 prin cele doua functii de populare directa\n";


z2.ret_re()=7; /*functia poate primi valori prin apel, pentru ca ea a fost scrisa
ca intorcand o referinta*/
z2.ret_im()=-5;

cout<<"Citim nr. complex z3 prin functia de citire propriu-zisa\n";


z3.citire();

//afisam cele 3 numere complexe


afisare(z1,"z1"); /*daca afisare ar fi fost metoda, si nu functie prieten, apelul
ar fi putut fi de forma: z1.afisare("z1");*/
afisare(z2,"z2");
afisare(z3,"z3");

system("pause");
return (0);
}

Subiect 1 var 2 Clasa si obiecul in OOP


Clasa in OOP
O clasa defineste un tip abstract de date. Asta înseamnă că pe langă datele definite, mai poate
conţine şi o serie de operaţii ce se efectuează pe acestea. Ca atare, o clasă va avea 2 parti in definitia sa,
si anume, componenta de date membru şi componenta de functii membru (metodele).

Forma sintactica a unei clase este urmatoarea:

class nume_clasa
{
[private:]
Date membru;
Functii membru;
[public:]
Date membru;
Functii membru;
[protected:]
Date membru;
Functii membru;
};
Datele şi metodele sunt definite sub incidenţa a 3 posibili specificatori de protecţie (private,
public şi protected). Elementele ce se găsesc sub private nu sunt vizibile decât în clasa respectivă, acest
specificator fiind şi cel implicit. Componentele ce se găsesc sub influenţa lui public pot fi accesate de
oriunde din clasă, respectiv, din afara acesteia. Cele care se găsesc sub incidenţa lui protected pot fi
accesate doar într-o ierarhie de clase, adică, clasa respectivă şi alte clase ce derivă din aceasta.

Obiectul
Obiectul este o instanţă de clasă, o referire a clasei, o dată a clasei. Declararea unui obiect se
face prin două metode:

1) Declaraţie automatică:

nume_clasa nume_obiect;

cu referirea la una din datele/metodele clasei: nume_obiect.data|metoda;

2) Declaraţie dinamică:

nume_clasa* nume_obiect;
nume_obiect = new nume_clasa;

Accesul în acest caz se face după următoarea declaraţie: nume_obiect->data|metoda;

O astfel de declaraţie de obiect are o durată de viaţă determinată de utilizator, adică, în momentul
în care acesta utilizează comanda delete nume_obiect; va curăţa zona de memorie ocupată de
respectivul obiect.

#include<iostream>
using namespace std;

class complex
{
float a,b; //a - p. reala, b - p. imaginara, presetate de private
public:
void citire(char* s)
{
cout<<"Introduceti nr. complex "<<s<<":\n";
cout<<"\tpartea reala= ";
cin>>a;
cout<<"\tpartea imaginara= ";
cin>>b;
}
void afisare(char* s)
{
cout<<"Nr. complex "<<s<<": ("<<a<<','<<b<<")\n";
}
complex aduna(complex z) //varianta 1 (transfer prin rezultat)
{
complex t;
t.a=a+z.a;
t.b=b+z.b;
return t;
}
void aduna(complex z, complex* t) //varianta 2 (transfer prin parametru adresa)
{
t->a=a+z.a;
t->b=b+z.b;
}
void aduna(complex z, complex& t) //varianta 3 (transfer prin parametru referinta)
{
t.a=a+z.a;
t.b=b+z.b;
}
};

int main()
{
//nr. complex z1 il vom declara ca si obiect automatic, iar z2 ca unul dinamic
complex z1, *z2;

//citim si afisam nr. complex z1


z1.citire("z1");
z1.afisare("z1");

//citim si afisam nr. complex z2


z2=new complex;
z2->citire("z2");
z2->afisare("z2");

//adunarea celor doua nr. complexe


complex s1,s2,s3,s4,s5,s6;
s1=z1.aduna(*z2); //varianta 1 cu z1 obiect curent
s2=z2->aduna(z1); //varianta 1 cu z2 obiect curent
z1.aduna(*z2,&s3); //varianta 2 cu z1 obiect curent
z2->aduna(z1,&s4); //varianta 2 cu z2 obiect curent
z1.aduna(*z2,s5); //varianta 3 cu z1 obiect curent
z2->aduna(z1,s6); //varianta 3 cu z2 obiect curent
s1.afisare("z1+z2");
s2.afisare("z1+z2");
s3.afisare("z1+z2");
s4.afisare("z1+z2");
s5.afisare("z1+z2");
s6.afisare("z1+z2");

//dealocare memorie ptr. obiectul dinamic


delete z2;

system("pause");
return (0);
}

Obiectul curent este obiectul care apelează funcţia, spre exemplu, în cazul z2->citire("z2"); obiect
curent este z2, în cazul s4.afisare("z1+z2"); obiect curent este s4.

Subiectul 2 Obiecte constructori si destructori


Subiect T2. Obiecte. Constructori şi destructori

Un obiect este o instanţiere a unei clase, adică, o dată de clasă, adică, o definire a unei clase.

Obiectele pot fi definite prin două moduri:

1) Declaraţie statică (automatică) – este de forma sintactică:


nume_clasa nume_obiect;
iar, o referare la una din datele sau metodele clasei, se face prin:
nume_obiect.data_membru; sau nume_obiect.functie_membru(linie_param_actuali);
2) Declaraţia dinamică – este de forma:
nume_clasa * nume_obiect = new nume_clasa;
Alocarea se face în zona de memorare Heap, iar durata de viaţă a unui obiect este determinată
de programator, un obiect putându-se “stinge” prin declaraţia: delete nume_obiect;
Referirea la una din metodele sau datele membru se face prin:
nume_obiect->data_membru; sau nume_obiect->functie_membru(linie_param_actuali);
sau
(*nume_obiect).data_membru; sau (*nume_obiect).functie_membru(linie_param_actuali);

Obiectul curent este cel care apelează o dată sau o metodă, fiind cel care îşi ia în sarcina data sau
metoda respectivă, se numeşte obiectul this, iar orice referire la datele sale se face prin declaraţia:

this->data(metoda); sau (*this).data(metoda);

Constructorul este o metodă a unei clase, ce permite iniţializare la declarare a unui obiect. Orice clasă
are un constructor definit, el nu se vede, fiind implicit, doar se apelează, de asemenea, tot implicit. Orice
scriere proprie de constructor, îl va suprascrie pe cel implicit, aşa că, dacă avem nevoie în declaraţii de
acesta, ele trebuie rescris. Constructorii sunt de mai multe feluri:

1) Constructor de iniţializare prin parametri


2) Constructor de iniţializare fără parametri
3) Constructor de iniţializare a unui obiect prin preluarea informaţiilor de la un alt obiect – acesta
se cheamă constructorul de copiere.

Orice funcţie constructor are numele acelaşi cu numele clasei din care provine şi nu are tip rezultat scris.

Destructorul este cel care ajută la dealocarea unui obiect, dacă nu se defineşte nici unul, atunci intră în
acţiune cel implicit, nu are tip rezultat, nu are corp de funcţie, iar numele coincide cu numele clasei,
precedat fiind însă de semnul “~”.

Exemplificare. Să se exemplifice utilizarea constructorilor şi destructorilor, precum şi definirea


obiectelor, pe lucrul cu vectori binari, adică, perechi de numere întregi de forma (a,b), unde a,b ∈ Z.

#include<iostream>
using namespace std;

class vb
{
int e1,e2;
public:
//constructor de initializare prin parametri
vb(int,int); //(1)
//constructor de initializare fara parametri, de forma celui implicit
vb(){} //(2)
//constructor de initializare prin copiere
vb(const vb&); //(3)
//functii pentru extragerea intr-o forma publica a elementelor vectorului
int& element1(); //(4)
int& element2(); //(5)
//destructor propriu
~vb(); //(6)
//functie de afisare continut
void afisare(char*); //(7)
};

vb::vb(int i, int j): e1(i), e2(j) {}

vb::vb(const vb& v): e1(v.e1), e2(v.e2) {}

int& vb::element1()
{
return e1;
}

int& vb::element2()
{
return e2;
}

vb::~vb()
{
cout<<"dealocare de memorie obiect\n";
}

void vb::afisare(char* s)
{
cout<<"Vectorul binar "<<s<<" este: ("<<e1<<','<<e2<<")\n";
}

int main()
{
vb v1(9,0); //apel al lui (1) - declaratie statica
vb* v2=new vb(4,5); //apel al lui (1) - declaratie dinamica
vb v3; //apel al lui (2)
v3.element1()=10; //apel al lui (4)
v3.element2()=-1; //apel al lui (5)
vb v4(v3); //apel al lui (3)

//afisarea:
v1.afisare("v1");
v2->afisare("v2");
v3.afisare("v3");
v4.afisare("v4");

delete v2; //apel al lui (6)

system("pause");
return (0);
}
Subiectul 3 Fisiere text
Fisiere text
Aplicatia 1. Se citeste un fisier text, Numere.txt, fisier ce contine numere intregi, despartite prin spatiu
si Enter. Sa se determine valorile extreme din acel fisier si suma tuturor elementelor.

#include<iostream>
#include<fstream>
using namespace std;

int main()
{
//P1: deschiderea fisierului
//varianta 1: prin constructor si clasa dedicata fisierelor de citire
ifstream f("d:\\numere.txt");
/*varianta 2: prin constructor si clasa pentru modul general de lucru cu fisiere
fstream f("d:\\numere.txt",ios::in);*/
/*varianta 3: prin functie de deschidere si obiect al unei clase pentru citire din
fisier
ifstream f;
f.open("d:\\numere.txt");*/
/*varianta 4: prin functie de deschidere si obiect al unei clase pentru modul
general de lucru cu fisiere
fstream f;
f.open("d:\\numere.txt",ios::in);*/

//P2: testarea deschiderii


if(!f)
throw new exception("Eroare la deschiderea fisierului\n");

//P3: manipularea fisierului, prin parcurgerea acestuia


int m,M,s; //m-minimul, M-maximul, s-suma
int x; //variabila in voi citi elementele intregi din fisier
f>>x; //citirea primului element din fisier
m=M=s=x;
//parcurgerea fisierului
while(!f.eof()) //==0
{
f>>x;
if(x<m)
m=x;
else
if(x>M)
M=x;
s+=x;
}

//P4: inchiderea fisierului text


f.close();

//transmiterea rezultatelor la consola


cout<<"Minimul din fisier: "<<m<<'\n';
cout<<"Maximul din fisier: "<<M<<'\n';
cout<<"Suma elementelor intregi din fisier: "<<s<<'\n';
system("pause");
return (0);
}

Aplicatia 2. Se citeste un fisier text, Litere1.txt, ce contine un mesaj textual. Sa se contorizeze aparitia
fiecarei vocale, precum si numarului tuturor consoanelor din fisier. Rezultatul nu se va transmite la
consola, ci, intr-un alt fisier text, Litere2.txt.

#include<iostream>
#include<fstream>
using namespace std;

int main()
{
ifstream f("d:\\litere1.txt");
if(!f)
throw new exception("Eroare la deschiderea fisierului de intrare\n");
int a,e,i,o,u,c; //numarul de aparitii a fiecarei vocale si a consoanelor
a=e=i=o=u=c=0;
char x;
while(!f.eof())
{
f>>x;
switch(x)
{
case 'a':
case 'A':{a++;break;}
case 'e':
case 'E':{e++;break;}
case 'i':
case 'I':{i++;break;}
case 'o':
case 'O':{o++;break;}
case 'u':
case 'U':{u++;break;}
default:
if((x>'a'&&x<='z')||(x>'A'&&x<='Z'))
c++;
};
}
f.close();

ofstream g("d:\\litere2.txt");
if(!g)
throw new exception("Eroare la deschiderea fisierului de iesire\n");
g<<"Nr. de aparitii a lui a|A: "<<a<<'\n';
g<<"Nr. de aparitii a lui e|E: "<<e<<'\n';
g<<"Nr. de aparitii a lui i|I: "<<i<<'\n';
g<<"Nr. de aparitii a lui o|O: "<<o<<'\n';
g<<"Nr. de aparitii a lui u|U: "<<u<<'\n';
g<<"Nr. de consoane: "<<c<<'\n';

system("pause");
return (0);
}
Subiectul 4 Fisiere binare
Fisiere binare
1. Se citeste de la tastatura o lista de produse, in ceea ce inseamna denumire si pret, informatia fiind
scrisa intr-un fisier binar. Se va scrie, apoi, un alt program, ce va prelua lista de produse din fisierul binar,
si o va transmite la consola.

//Fisier_binar.h

#include <iostream>
#include <fstream>
using namespace std;

#define dim 50 //numarul maxim de produse

struct produs
{
char denumire[30];
float pret;
};

produs lista[dim]; //o lista de 'dim' produse

//Aplicatia1.cpp – este aplicatia prin intermediul careia se inscriu date in fisierul binar Produse.dat

#include"fisier_binar.h"

int main()
{
//P1: deschiderea fisierului
ofstream f("d:\\produse.dat",ios::binary);
//P2: testarea deschiderii
if(!f)
throw new exception("Eroare la deschiderea fisierului");

int i=0;
char c;

//P3: populez vectorul lista cu lista de produse dorita


do{
cout<<"Denumirea produsului: ";
lista[0].denumire[0]=' ';
cin.ignore(); //golirea buffer-ului
cin.getline(lista[i].denumire,40,'\n');
cout<<"Pretul: ";
cin>>lista[i].pret;
i++;
cout<<"Se doreste repetarea actiunii? (d/n): ";
cin>>c;
} while(c != 'n' && c != 'N' && i<=dim);

//P4: se completeaza fisierul binar din lista de produse


f.write((char*)lista, dim*sizeof(produs));
//P5: se inchide fisierul
f.close();

system("pause");
return (0);
}

//Aplicatia2.cpp – este aplicatia prin intermediul careia se preiau date din fisierul binar Produse.dat, se
scriu la consola, putandu-se realiza diverse aplicatii pe acestea

#include"fisier_binar.h"

int main()
{
//P1: deschiderea fisierului binar, spre citire din el
ifstream f("d:\\produse.dat",ios::binary);
//P2: testarea deschiderii
if(!f)
throw new exception ("Eroare la deschiderea fisierului");

//P3: citirea listei din fisier


f.read((char*)lista, dim*sizeof(produs));

int i=0;

//P4: manipularea informatiei din lista extrasa din fisierul binar


while(strcmp(lista[i].denumire,""))
{
cout <<"Denumire produs "<<i+1<<": "<<lista[i].denumire<<endl;
cout <<"Pret produs "<<i+1<<": "<<lista[i].pret<<endl;
i++;
}

//P5: inchiderea fisierului


f.close();

system("pause");
return (0);
}

2. Se citesc un număr de maxim 20 de numere complexe, într-un fişier binar, urmând ca apoi să se
deschidă respectivul fişier, să se afişeze la consolă respectivele numere, şi să se efectueze produsul lor.

//Complex.h – clasa header

#include <iostream>
#include <fstream>
using namespace std;

#define dim 20 //numarul maxim de numere complexe

struct complex
{
float a,b; //a-partea reala, b-partea imaginara
char nume[3];
};

complex vector[dim]; //vectorul de numere complexe

//Aplicatia 1. Aplicatia care transfera informatia in fisier

#include"Complex.h"

int main()
{
//P1: deschiderea fisierului spre scriere in el
ofstream f("d:\\complexe.dat",ios::binary);
//P2: testarea deschiderii
if(!f)
throw new exception("Eroare la deschiderea fisierului");

int i=0;
char c;

//P3: populez vectorul cu numere complexe dorite


do{
cout<<"Introduceti nr. complex: ";
cin>>vector[i].nume;
cout<<"\tpartea reala: ";
cin>>vector[i].a;
cout<<"\tpartea imaginara: ";
cin>>vector[i].b;
i++;
cout<<"Se doreste repetarea actiunii? (d/n): ";
cin>>c;
} while(c != 'n' && c != 'N' && i<=dim);

//P4: se completeaza fisierul binar din lista de numere complexe


f.write((char*)vector, dim*sizeof(complex));

//P5: se inchide fisierul


f.close();

system("pause");
return (0);
}

//Aplicatia 2. Preluarea informatiei din fisierul binar

#include"Complex.h"

int main()
{
//P1: deschiderea fisierului binar, spre citire din el
ifstream f("d:\\complexe.dat",ios::binary);
//P2: testarea deschiderii
if(!f)
throw new exception ("Eroare la deschiderea fisierului");
//P3: citirea listei din fisier
f.read((char*)vector, dim*sizeof(complex));

int i=0;

//P4: manipularea informatiei din lista extrasa din fisierul binar


while(strcmp(vector[i].nume,""))
{
cout<<"Numarul complex "<<vector[i].nume;
cout <<'('<<vector[i].a<<','<<vector[i].b<<")\n";
i++;
}

//P5: inchiderea fisierului


f.close();

complex t;
t.a=t.b=0;
for(int j=0;j<i;j++)
t.a+=vector[j].a;
for(int j=0;j<i;j++)
t.b+=vector[j].b;
cout<<"\nNr. complex suma: ("<<t.a<<','<<t.b<<")\n";

system("pause");
return (0);
}

3. Se citesc un număr de maxim 20 de numere rationale, într-un fişier binar, urmând ca apoi să se
deschidă respectivul fişier, să se afişeze la consolă respectivele numere, şi să se efectueze suma lor.

//Rational.h

#include <iostream>
#include <fstream>
using namespace std;

#define dim 20 //numarul maxim de numere rationale

struct rational
{
char nume; //numele numarului rational (R, Q, P, ...)
int a,b; //a-numaratorul, b-numitorul
int cmmdc(int x, int y)
{
while(x!=y)
{
if(x>y)
x=x-y;
else
y=y-x;
}
return x;
}
void ireductibil()
{
if(a==0)
{
b=1;
return;
}
if(b<0)
{
a=-a;
b=-b;
}
if(abs(a)!=1 && b!=1)
{
int d=cmmdc(abs(a),b);
a/=d;
b/=d;
}
}
};

rational vector[dim]; //vectorul de numere rationale

//Aplicatia 1. Aplicatia care transfera informatia in fisier

#include"Rational.h"

int main()
{
//P1: deschiderea fisierului spre scriere in el
ofstream f("d:\\rationale.dat",ios::binary);
//P2: testarea deschiderii
if(!f)
throw new exception("Eroare la deschiderea fisierului");

int i=0;
char c;

//P3: populez vectorul cu numere rationale dorite


do{
cout<<"Introduceti nr. rational: ";
cin>>vector[i].nume;
cout<<"\tnumaratorul: ";
cin>>vector[i].a;
do{
cout<<"\tnumitorul: ";
cin>>vector[i].b;
}while(vector[i].b==0);
vector[i].ireductibil();
i++;
cout<<"Se doreste repetarea actiunii? (d/n): ";
cin>>c;
} while(c != 'n' && c != 'N' && i<=dim);

//P4: se completeaza fisierul binar din lista de numere rationale


f.write((char*)vector, dim*sizeof(rational));
//P5: se inchide fisierul
f.close();

system("pause");
return (0);
}

//Aplicatia 2. Preluarea informatiei din fisierul binar

#include"Complex.h"

int main()
{
//P1: deschiderea fisierului binar, spre citire din el
ifstream f("d:\\rationale.dat",ios::binary);
//P2: testarea deschiderii
if(!f)
throw new exception ("Eroare la deschiderea fisierului");

//P3: citirea listei din fisier


f.read((char*)vector, dim*sizeof(rational));

int i=0;

//P4: manipularea informatiei din lista extrasa din fisierul binar


while(vector[i].nume!='NULL')
{
cout<<"Numarul complex "<<vector[i].nume;
cout <<'('<<vector[i].a<<','<<vector[i].b<<")\n";
i++;
}

//P5: inchiderea fisierului


f.close();
/*
complex t;
t.a=t.b=0;
for(int j=0;j<i;j++)
t.a+=vector[j].a;
for(int j=0;j<i;j++)
t.b+=vector[j].b;
cout<<"\nNr. complex suma: ("<<t.a<<','<<t.b<<")\n";
*/
system("pause");
return (0);
}

#include"Complex.h"

int main()
{
//P1: deschiderea fisierului binar, spre citire din el
ifstream f("d:\\rationale.dat",ios::binary);
//P2: testarea deschiderii
if(!f)
throw new exception ("Eroare la deschiderea fisierului");

//P3: citirea listei din fisier


f.read((char*)vector, dim*sizeof(rational));

int i=0;

//P4: manipularea informatiei din lista extrasa din fisierul binar


while(strcmp(vector[i].nume,""))
{
cout<<"Numarul complex "<<vector[i].nume;
cout <<'('<<vector[i].a<<','<<vector[i].b<<")\n";
i++;
}

//P5: inchiderea fisierului


f.close();

//inmultirea numerelor rationale


rational t;
t.a=t.b=1;
for(int j=0;j<i;j++)
t.a*=vector[j].a;
for(int j=0;j<i;j++)
t.b*=vector[j].b;
t.ireductibil();
cout<<"\nNr. rational produs: ("<<t.a<<','<<t.b<<")\n";

system("pause");
return (0);
}

Subiectul 5 Mostenirea simpla


Subiect 5. Mostenirea simpla
Mostenirea simpla este o relatie binara intre 2 clase,una fiind clasa de baza,alta fiind clasa derivata.Acea
clasa derivate va prelua toate proprietatile clasei de baza pe care o mosteneste.Dintre problem aparute
pe principiul mostenirii sunt urmatoarele:

-daca intr-o clasa derivate declaram un obiect al unei clase de baza urmand ca acesta sa apeleze
elemente protejate in ierarhie definite in clasa de baza,acestea nu vor fi accesibile

-nu se pot transfera informatii dinspre clasa de baza inspre clasa derivata decat in urma supraincarcarii
explicite a operatorului =(operatorul de atribuire)

-constructorii si destructorii sunt metode care nu se mostenesc,astfel incat constructorul unei clase
derivate apeleaza intai constructorul clasei de baza,in cazul destructorilor,operatiunea facandu-se invers
-daca in intermediul unei ierarhii de clasa denumirile unei date sau antetele unor metode
coincid,prioritare vor fi cele din clasa derivata, cele din clasa de baza fiind accesate prin:
nume_clasa_baza::data/metoda;

Sintaxa unei relatii de mostenire:

class baza
{
private:
date|metode
protected:
date|metode
public:
date|metode
};

class derivata: private|public baza


{
elemente_specifice_clasei_derivate
};

Explicatii:

Dupa cum se vede apare un nou specificator de protectie(protected) utilizabil pentru accesibilitatea
datelor intr-o ierarhie de clase.

In linia de mostenire apare private/public, utilizarea lor se poate observa in tabelul de mai jos cu
controlul accesului la membrii mosteniti:

Elementele in clasa de baza Specificatorul din lista de Rezultatul in clasa derivata


mostenire
private private inaccesibil
protected private private
public private private
private public inaccesibil
protected public protected
public public public

Se considera o clasa Pereche, ce contine date despre o pereche de numere intregi si un constructor ce
va permite initierea la declaratie a informatiei. Din clasa Pereche, deriva o clasa Complex, care, preia
informatia din Pereche, ataseaza un nume, si prelucreaza numerele complexe, prin afisarea si suma
acestora. De asemenea, se cere supraîncarcarea operatorului “=” pentru realizarea operaţiilor de
conversie dinspre Pereche spre Complex.

1) Varianta simpla, fara operatorul de “=” supraincarcat

#include<iostream>
using namespace std;
class pereche
{
protected:
int a,b;
public:
pereche(int x, int y)
{
a=x;
b=y;
}
};

class complex:pereche //private pereche


{
char* s;
public:
complex(int x=0, int y=1, char p[]=NULL):pereche(x,y)
{
s=p;
}
friend ostream& operator<<(ostream& x, complex z)
{
x<<"Nr. complex "<<z.s<<" este: ("<<z.a<<','<<z.b<<")\n";
return x;
}
};

int main()
{
complex z1(3,4,"z1"), z2(-6,2,"z2");

//afisarea numerelor complexe


cout<<z1;
cout<<z2;

system("pause");
return (0);
}

2) Varianta extinsa – cu operatorul de atribuire supraincarcat

#include<iostream>
using namespace std;

class pereche
{
protected:
int a,b;
public:
pereche(int x, int y)
{
a=x;
b=y;
}
int& parte_re()
{
return a;
}
int& parte_im()
{
return b;
}
};

class complex:pereche //private pereche


{
char* s;
public:
complex(int x=0, int y=1, char p[]=NULL):pereche(x,y)
{
s=p;
}
friend ostream& operator<<(ostream& x, complex z)
{
x<<"Nr. complex "<<z.s<<" este: ("<<z.a<<','<<z.b<<")\n";
return x;
}
void operator=(pereche& r)
{
(*this).a=r.parte_re();
b=r.parte_im();
}

};

int main()
{
complex z1(3,4,"z1"), z2(-6,2,"z2");

//afisarea numerelor complexe


cout<<z1;
cout<<z2;

pereche t(5,-9);
complex z3(0,0,"z3");
z3=t;
cout<<z3;

system("pause");
return (0);
}

Subiectul 6 Clase prieten


Clase prieten
O clasă prieten este o clasă care are antetul definit într-o altă clasă, putând accesa elementele de orice
natură din clasa respectivă.

Avantajul utilizării claselor prieten este acela de a a vea pobilitatea accesului datelor ce se găsesc sub
influenţa specificatorului private.
Sintaxa unei clase prieten este următoarea:

class clasa2;

class clasa1
{
//elemente specifice clasei initiale
friend class clasa2; /*clasa2 va fi clasa priten clasei clasa1, adica, va avea
acces la toate elementele, de orice natura, ale clasa1*/
};

class clasa2
{
//elemente specifice clasei prieten
};

Exemplu:

Se consideră o clasă Pereche, cu două elemente, numere întregi, să se construiască o altă clasă,
Complex, care să acceseze elementele clasei Pereche, şi să realizeze operaţii de bază pe numere
complexe, adică, introducerea şi afişarea acestora.

//Varianta 1: cea fara utilizare de constructori in clasa initiala

#include<iostream>

using namespace std;

class complex;

class pereche
{
int a,b;
friend class complex;
};

class complex
{
pereche p;
char* n;
public:
complex(int x, int y, char s[])
{
p.a=x;
p.b=y;
n=s;
}

void afis()
{
cout<<"Nr. complex "<<n<<" este: ("<<p.a<<','<<p.b<<")\n";
}
};
int main()
{
complex z1(2,3,"z1");
complex z2(-1,8,"z2");
z1.afis();
z2.afis();
system("pause");
return (0);
}

//Varianta 2: cea cu utilizare de constructori in clasa initiala

#include<iostream>

using namespace std;

class complex;

class pereche
{
int a,b;
friend class complex;
public:
pereche(int x, int y)
{
a=x;
b=y;
}
};

class complex
{
char* n;
public:
complex(char s[]=NULL, int x=0, int y=1)
{
pereche p(x,y);
n=s;
}
void afis(pereche p)
{
cout<<"Nr. complex "<<n<<" este: ("<<p.a<<','<<p.b<<")\n";
}
};

int main()
{
pereche p1(2,3);
complex z1("z1");
pereche p2(-9,7);
complex z2("z2");
z1.afis(p1);
z2.afis(p2);
system("pause");
return (0);
}
Subiectul 7 Polimorfisul
Polimorfismul. Clase abstracte
Polimorfismul: capacitatea unui obiect de a lua forme multiple. Are la bază procesul de moştenire şi
existenţa funcţiilor virtuale.

Principiul de functionare este urmatorului: intr-o ierarhie de clase, se declara un obiect dinamic la clasa
cea mai de bază şi se face apoi pointarea la toate celelalte clase derivate din clasa de bază.
Polimorfismul are la bază utilizarea funcţiilor virtuale.

O clasă abstractă este o clasă definită în vârful unei ierarhii, de următoarea formă:

class clasa_abstracta
{
virtual tip_rez functia1(linie_parametri)=0;
virtual tip_rez functia2(linie_parametri)=0;
virtual tip_rez functia3(linie_parametri)=0;
.....................
};

unde functia1, functia2, …, sunt funcţii virtual pure (sunt precedate de cuvântul virtual, nu au corp
definit de funcţie, antetul este egalat cu 0 şi se incheie cu “;”).

Exemplu:

Să se scrie o ierarhie de clase, pornind de la o clasă virtuală, pentru citirea, calculul ariei şi al
perimetrului, pentru cazul cercului, al tringhiului si al dreptunghiului.

#include<iostream>
#define pi 3.14

using namespace std;

class home //clasa abstracta


{
public:
virtual void citire()=0;
virtual double aria()=0;
virtual double perimetru()=0;
};

class cerc:public home


{
double r;
public:
void citire()
{
cout<<"Citim cercul\n";
cout<<"\tintroduceti raza: ";
cin>>r;
}
double aria()
{
return pi*r*r;
}
double perimetru()
{
return 2*pi*r;
}
};

class triunghi:public home


{
double a,b,c;
public:
void citire()
{
cout<<"Citim triunghiul\n";
cout<<"\ta=";
cin>>a;
cout<<"\tb=";
cin>>b;
do
{
cout<<"\tc=";
cin>>c;
}while((a+b<=c)||(a+c<=b)||(b+c<=a));
}
double aria()
{
double s=(a+b+c)/2;
return sqrt(s*(s-a)*(s-b)*(s-c));
}
double perimetru()
{
return a+b+c;
}
};

class dreptunghi:public home


{
double l,L;
public:
void citire()
{
cout<<"Citim dreptunghiul\n";
cout<<"\tl=";
cin>>l;
cout<<"\tL=";
cin>>L;
}

double aria()
{
return l*L;
}
double perimetru()
{
return 2*l+2*L;
}

};

int main()
{
home* x; //aplicarea polimorfismului

//cazul cercului
x=new cerc;
x->citire();
cout<<"Aria cercului: "<<x->aria()<<'\n';
cout<<"Perimetrul cercului: "<<x->perimetru()<<'\n';

cout<<'\n';

//cazul triunghiului
x=new triunghi;
x->citire();
cout<<"Aria triunghiului: "<<x->aria()<<'\n';
cout<<"Perimetrul triunghiului: "<<x->perimetru()<<'\n';

//cazul dreptunghiului
x=new dreptunghi;
x->citire();
cout<<"Aria dreptunghiului: "<<x->aria()<<'\n';
cout<<"Perimetrul dreptunghiului: "<<x->perimetru()<<'\n';

system("pause");
return (0);
}

Subiectul 8 Functii generice


Functii generice
Folosindu-se funcţii generice, pentru valori numerice de orice tip, să se realizeze operaţii pe vectori
(citire, afişare şi valori extreme).

#include<iostream>
#define dim 50
using namespace std;

template <class X> void citire(X[],int*); //citirea


template <class X> void afisare(X[],int); //afisarea
template <class X> X suma(X[],int); //suma
template <class X> void extreme(X[],int,X&,X&); //extremele din sir

template <class X>


void citire(X a[], int* n)
{
do{
cout<<"Dati dimensiunea sirului: ";
cin>>*n;
}while(*n<=0 || *n>dim);
cout<<"Introduceti elementele:\n";
for(int i=0;i<*n;i++)
{
cout<<"\telementul "<<i+1<<"= ";
cin>>a[i];
}
}

template <class X>


void afisare(X a[], int n)
{
cout<<"Sirul este: ";
for(int i=0;i<n;i++)
cout<<a[i]<<' ';
cout<<'\n';
}

template <class X>


X suma(X a[], int n)
{
X s=0;
for(int i=0;i<n;i++)
s+=a[i];
return s;
}

template <class X>


void extreme(X a[], int n, X& min, X& max)
{
min=max=a[0];
for(int i=1;i<n;i++)
if(min>a[i])
min=a[i];
else
if(max<a[i])
max=a[i];
}

int main()
{
int a[dim];
double b[dim];

int n,m;

cout<<"PENTRU NUMERE INTREGI\n";


citire(a,&n);
afisare(a,n);

cout<<'\n';

cout<<"PENTRU NUMERE REALE\n";


citire(b,&m);
afisare(b,m);
cout<<'\n';

cout<<"SUMA NUMERELOR INTREGI SI REALE\n";


cout<<"\tsuma intregilor: "<<suma(a,n)<<'\n';
cout<<"\tsuma numerelor reale: "<<suma(b,m)<<'\n';

system("pause");
return (0);
}

Subiectul 9A clase generice


Clase generice
Operatii pe matrice, intr-o clasa generica.
#include<iostream>
#include<iomanip>

using namespace std;


template <class T>
class matrice
{
int m,n; // m - numarul de linii, n - numarul de coloane
T* mat; // matricea, pentru se va aloca memorie in zona de memorare HEAP
public:
matrice(int=1,int=1); // constructor de initializare cu parametri
T* operator()(int,int); /* supraincarcarea operatorului special 'apel de
functie' pentru determinarea unui element al
matricei dintr-o anumita pozitie, pozitie data ca parametru*/
friend istream& operator>>(istream&,matrice<T>&); /*supraincarcarea operatorului
'extragere din flux' pentru citirea elementelor unei matrice */
friend ostream& operator<<(ostream&,matrice<T>); /*supraincarcarea operatorului
'insertie in flux' pentru afisarea elementelor unei matrice */
};

/* constructor de initializare cu parametri */


template <class T>
inline matrice<T>::matrice(int i,int j): m(i), n(j)
{
mat=new T[m*n]; /* alocam memorie suficienta in zona HEAP pentru pastrarea
unui tablou m*n elemente intregi */
}

/* supraincarcarea operatorului special 'apel de functie' pentru determinarea unui


element al matricei dintr-o anumita pozitie, pozitie data ca parametru */
template <class T>
T* matrice<T>::operator()(int i,int j)
{
return mat+i*n+j; /* adresa elementului de pe pozitia de linie i si coloana j a
unei matrice */
}

/* supraincarcarea operatorului 'extragere din flux' pentru citirea elementelor unei


matrice */
template <class T>
istream& operator>>(istream& x,matrice<T>& a)
{
for(int i=0;i<a.m;i++)
for(int j=0;j<a.n;j++)
{
cout<<"\telem["<<i+1<<"]["<<j+1<<"]= ";
x>>*a(i,j); // apel al operatorului '()' supraincarcat
}
return x;
}

/* supraincarcarea operatorului 'insertie in flux' pentru afisarea elementelor unei


matrice */
template <class T>
ostream& operator<<(ostream& x,matrice<T> a)
{
for(int i=0;i<a.m;i++)
{
for(int j=0;j<a.n;j++)
x<<setw(6)<<*a(i,j);
x<<endl;
}
return x;
}

int main()
{
int m,n; // m - nr de linii, n - nr de coloane

cout<<"Dati dimensiunea matricelor:\n";


cout<<"\tnumarul de linii: ";
cin>>m;
cout<<"\tnumarul de coloane: ";
cin>>n;
matrice<int> a(m,n),b(m,n); // apel al constructorului de initializare cu
parametri

cout<<"Citim matricea A:\n";


cin>>a; // apel al functiei ce supraincarca operatorul '>>'
cout<<"Citim matricea B:\n";
cin>>b;

cout<<endl<<"Dati o tasta ptr. a continua...";


cin.get();
system("cls");

cout<<"Afisam matricea A:\n";


cout<<a; // apel al functiei ce supraincarca operatorul '<<'
cout<<"Afisam matricea B:\n";
cout<<b;

system("pause");
return (0);
}
Subiectul 9B Supraincarcarea opertorilor speciali
Operatorul indexare si atribuire

//VARIANTA 1: ALOCARE DE MEMORIE STATICA

#include<iostream>
using namespace std;
#define dim 512
typedef int sir[dim]; //am definit un tip de date, cu numele 'sir', elementele fiind
intregi, iar dimensiunea rezervata a sirului tinuta in constanta dim

class vector
{
sir a; //vectorul
int n; //dimensiunea citita a vectorului
public:
vector(const vector&); //constructor de copiere, pentru transfer la declaratie a
datelor intr-un alt vector
vector(){} //pentru faptul ca exista un alt vector definit, cel implicit va fi
suprascris, iar prin aceasta declaratie il vom rescrie
int& operator[](int); //operatorul special '[]' (indexare|matrice) supraincarcat
//citirea vectorului n-dimensional
friend istream& operator>>(istream&,vector&); //cin>>v; v(vector)
//afisarea vectorului
friend ostream& operator<<(ostream&,vector); //cout<<v;
//operatorul de atribuire '=' supraincarcat
vector operator=(vector);
};

vector::vector(const vector& v):n(v.n)


{
for(int i=0;i<n;i++)
a[i]=v.a[i];
}

int& vector::operator[](int i)
{
return a[i];
}

istream& operator>>(istream& x,vector& v)


{
cout<<"Introduceti elementele vectorului:\n";
do{
cout<<"\tnumarul de elemente: ";
x>>v.n;
}while(v.n<=0 || v.n>dim);
cout<<"\tdati elementele:\n";
for(int i=0;i<v.n;i++)
{
cout<<"\t\telementul "<<i+1<<"= ";
x>>v[i];
}
return x;
}
ostream& operator<<(ostream& x,vector v)
{
x<<"Vectorul = ";
for(int i=0;i<v.n;i++)
x<<v[i]<<' ';
x<<'\n';
return x;
}

vector vector::operator=(vector v)
{
n=v.n;
for(int i=0;i<n;i++)
a[i]=v[i];
return *this;
}

int main()
{
vector v;

//citirea si afisarea
cin>>v;
cout<<"V: "<<v;

vector w;
w=v;
cout<<"W: "<<w;

system("pause");
return (0);
}

//VARIANTA 2: ALOCARE DE MEMORIE DINAMICA

#include<iostream>
using namespace std;
class vector
{
int n; //numarul de elemente
int *a; //tabela de coeficienti
public:
vector(int = -1); //constructor de initializare cu parametri mpliciti
vector(vector&); //constructor de initializare prin transfer
int& operator[](int); //operatorul 'indexare' supraincarcat (returneaza un anumit
element de pepozitia indicataprinparametru)
friend istream&operator>>(istream&, vector&); //citirea unui vector
friend ostream&operator<<(ostream&, vector); //afisarea unui vector
int operator==(vector&); //verificarea dc. doi vectori coincid
vector& operator=(vector&); //operatorul 'atribuire' supraincarcat pentru
transferul intre doi vectori
};
inline vector::vector(int x) : n(x)
{
a = new int[n]; //rezervarea spatiului de memorie in Heap
}

inline vector::vector(vector& v) : n(v.n)


{
a = new int[n];
int i = 0;
while (i<= n)
a[i++] = v.a[i];
}

inline int& vector::operator[](int x)


{
return a[x];
}

istream& operator>>(istream& x, vector& v)


{
cout<<"\tintroduceti elementele:\n";
for (int i = 0; i < v.n; i++)
{
cout<<"\t\telementul ["<<i<<"]= ";
x>>v[i]; //apel al operatorul '[]', altfel, ar fi trebuitscris 'p.cf[i]'
}
return x;
}

ostream&operator<<(ostream& x, vector v)
{
x<<"Vectorul este: ";
for(int i=0;i<v.n;i++)
x<<v[i];
x<<'\n';
return x;
}

int vector::operator==(vector& v)
{
int e = 1;
if (n != v.n)
e = 0;
else
for (int i = 0; i<= v.n && e == 1; i++)
if (a[i] != v[i])
e = 0;
return e;
}

vector& vector::operator=(vector& v)
{
if(!(*this==v))
{
delete a; /*se elibereazaspatiulocupat de pointerulpentrusirul
reprezentatfiindprinobiectul curent*/
a = new int[v.n]; /*se aloca spatiu extins nou pentru pointerul sirului
reprezentatprinobiectul current*/
n = v.n; /*se copiaza noua dimensiune, cu preluare din obiectultransmis
ca parametru*/
//se copiaza continutul sirului din celtransmis ca parametru
for (int i = 0; i< n; i++)
a[i] = v[i]; //copiere element cu element pepozitii
}
return *this;
}

int main()
{
vector v1(3), v2;

cin>>v1;

v2=v1;

cout<<v2;

system("pause");
return (0);
}

Subiectul 10 Aplicatie complete OOP


1. Vectorul n-dimensional
#include<iostream>
using namespace std;
#define dim 512
typedef int sir[dim]; //am definit un tip de date, cu numele 'sir', elementele fiind
intregi, iar dimensiunea rezervata a sirului tinuta in constanta dim

struct extrem
{
int m,M;
};

class vector
{
sir a; //vectorul
int n; //dimensiunea citita a vectorului
bool prim(int); //verificarea daca un numar este prim
int cmmdc(int,int); //cmmdc-ul a doua numere intregi
public:
vector(const vector&); //constructor de copiere, pentru transfer la declaratie a
datelor intr-un alt vector
vector(){} //pentru faptul ca exista un alt vector definit, cel implicit va fi
suprascris, iar prin aceasta declaratie il vom rescrie
int& operator[](int); //operatorul special '[]' (indexare|matrice) supraincarcat
//citirea vectorului n-dimensional
friend istream& operator>>(istream&,vector&); //cin>>v; v(vector)
//afisarea vectorului
friend ostream& operator<<(ostream&,vector); //cout<<v;

int operator+(); //adunarea elementelor: +v;


int operator*(); //inmultirea: *v;
int operator*(vector); //rpodusul scalar a doi vectori
float operator-(); //media aritmetica: -v;
extrem operator!(); //valorile extreme din sir
vector operator()(); //sortarea unui vector, prin operatorul special '()' (apel de
functie) supraincarcat
int operator()(int); //cautarea unui anumit element, cu determinarea primei
pozitii pe care se gaseste
vector operator~(); //sirul de numere prime dintr-un vector
int operator&(); //cmmdc-ul elementelor din sir
};

bool vector::prim(int e)
{
bool i=true;
if(e==1||e==2)
return i;
if(e%2==0)
{
i=false;
return i;
}
for(int i=3;i*i<=e;i++)
if(e%i==0)
{
i=false;
return i;
}
return i;
}

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


{
while(a!=b)
if(a>b)
a=a-b;
else
b=b-a;
return a;
}

vector::vector(const vector& v):n(v.n)


{
for(int i=0;i<n;i++)
a[i]=v.a[i];
}

int& vector::operator[](int i)
{
return a[i];
}

istream& operator>>(istream& x,vector& v)


{
cout<<"Introduceti elementele vectorului:\n";
do{
cout<<"\tnumarul de elemente: ";
x>>v.n;
}while(v.n<=0 || v.n>dim);
cout<<"\tdati elementele:\n";
for(int i=0;i<v.n;i++)
{
cout<<"\t\telementul "<<i+1<<"= ";
x>>v[i];
}
return x;
}

ostream& operator<<(ostream& x,vector v)


{
x<<"Vectorul = ";
for(int i=0;i<v.n;i++)
x<<v[i]<<' ';
x<<'\n';
return x;
}

#include"Vector.h"

int main()
{
vector v;

//citirea si afisarea
cin>>v;
cout<<v;

system("pause");
return (0);
}

2. Polinomul
#include<iostream>
using namespace std;
class polinom
{
int gr; //gardulpolinomului
int *cf; //tabela de coeficienti
public:
polinom(int = -1); //constructor de initializare cu parametriimpliciti
polinom(polinom&); //constructor de initializareprin transfer
~polinom(); //destructor
int& operator[](int); //operatorul 'indexare' supraincarcat (returneaza un anumit
element de pepozitiaindicataprinparametru)
friend istream&operator>>(istream&, polinom&); //citirea unui polinom
friend ostream&operator<<(ostream&, polinom); //afisarea unui polinom
polinom operator+(polinom&); //adunarea a douapolinoame
polinom operator*(polinom&); //inmultirea a douapolinoame
polinom& operator=(polinom&); //operatorul 'atribuire'
supraincarcatpentrutransferulcoeficientilordintr‐un polinomintr‐altul
int operator==(polinom&); //verificarea dc. doua siruri polinomiale coincid
double operator|(int); //valoarea unui polinom intr‐un punct
(punctulesteindicatprinparametru)
};

inline polinom::polinom(int x) : gr(x)


{
cf = new int[gr + 1]; //rezerva grad+1 spatiiptr. memorareapolinomului
int i = 0;
while (i<= gr)
cf[i++] = 0;
}

inline polinom::polinom(polinom&p) : gr(p.gr)


{
cf = new int[gr + 1];
int i = 0;
while (i<= gr)
cf[i++] = p.cf[i];
}

inline polinom::~polinom()
{
delete[]cf; //curatacontinutuldintr‐un polinom
}

inline int& polinom::operator[](int x)


{
return cf[x];
}

istream&operator>>(istream&x, polinom&p)
{
cout<<"\tintroduceti coenficientii:\n";
for (int i = p.gr; i>= 0; i--)
{
cout<<"\t\tcoeficient ["<<i<<"]= ";
x>>p[i]; //apel al operatorul '[]', altfel, ar fi trebuitscris 'p.cf[i]'
}
return x;
}

ostream&operator<<(ostream& x, polinom p)
{
x<<p[p.gr]<<"*x^"<<p.gr;
for (int i = p.gr - 1; i>= 1; i--)
if (p[i]>= 0)
x<<'+'<<p[i]<<"*x^"<<i;
else
x<<p[i]<<"*x^"<<i;
if (p[0]>= 0)
x<<'+'<<p[0];
else
x<<p[0];
cout<<'\n';
return x;
}
polinom&polinom::operator=(polinom&p)
{
if(!(*this==p))
{
delete cf; /*se elibereazaspatiulocupat de pointerulpentrusirul
reprezentatfiindprinobiectul current*/
cf = new int[p.gr + 1]; /*se alocaspatiuextinsnoupentrupointerulsirului
reprezentatprinobiectul current*/
gr = p.gr; /*se copiazanouadimensiune, cu preluare din obiectultransmis
ca parametru*/
//se copiazacontinutulsirului din celtransmis ca parametru
for (int i = 0; i<= gr; i++)
cf[i] = p[i]; //copiere element cu element pepozitii
}
return *this;
}

polinom polinom::operator+(polinom& p)
{
int x, y;
(gr >= p.gr) ? (x = gr, y = p.gr) : (x = p.gr, y = gr); /* se foloseste operatorul
conditional: expr_test?expr_adv:expr_fals */
polinom r(x);
for (int i = 0; i<= y; i++)
r[i] = (*this)[i] + p[i];
if (x == y)
return r;
if (x == gr)
for (int i = y + 1; i<= x; i++)
r[i] = (*this)[i];
else
for (int i = y + 1; i<= x; i++)
r[i] = p[i];
return r;
}
polinom polinom::operator *(polinom&r)
{
polinom g(gr+r.gr);
for (int i = 0; i<= gr; i++)
for (int j = 0; j <= r.gr; j++)
g[i + j] += cf[i] * r[j];
return g;
}

int polinom::operator==(polinom&p)
{
int a = 1;
if (gr != p.gr)
a = 0;
else
for (int i = 0; i<= p.gr && a == 1; i++)
if (cf[i] != p[i])
a = 0;
return a;
}

double polinom::operator|(int x)
{
double r = 0;
for (int i = 0; i<= gr; i++)
r += cf[i] * (pow((float)x, i));
return r;
}

int main()
{
//citimpolinomul P
cout<<"Dati datele polinomului P\n";
cout<<"\tintroduceti gradul: ";
int x; //dimensiuneareala a polinomului
cin>> x;
polinom p(x);
cin>> p;
//citimpolinomul Q
cout<<"Dati datele polinomului Q\n";
cout<<"\tintroduceti gradul: ";
int y;
cin>> y;
polinom q(y);
cin>> q;
//afisareapolinoamelor
cout<<"Polinomul P: "<< p;
cout<<"Polinomul Q: "<< q;
//verificareadacadouapolinoamecoincid
cout<<"1 = polinoame identite | 0 = polinoame diferite: "<< (p == q) <<'\n';
//tranferul datelor dinspre un polinom spre un altul
polinom r;
r = p;
cout<<"Polinomul R: "<< r;
//valoareaunuipolinomintr‐un punct
cout<<"Dati punctul in care se dorestevaloareapolinomului P: ";
int z;
cin>> z;
cout<<"Valoarea lui P in "<< z <<"= "<< (p | z) <<'\n';
//adunarea a douapolinoame
polinom s;
s = p + q;
cout<<"Polinomul P+Q: "<<s ;
//inmultirea a douapolinoame
polinom k;
k = p*q;
cout<<"Polinomul P*Q: "<< k <<'\n';

system("pause");
return (0);
}

3. Matricea bidimensionala
//Matrice.h

#include<iostream>
#include<iomanip>
using namespace std;
class matrice
{
int m,n; // m - numarul de linii, n - numarul de coloane
int* mat; // matricea, pentru se va aloca memorie in zona de memorare HEAP
public:
matrice(int=1,int=1); // constructor de initializare cu parametri
int* operator()(int,int); /* supraincarcarea operatorului special 'apel de
functie' pentru determinarea unui element al
matricei dintr-o anumita pozitie, pozitie data ca parametru*/
friend istream& operator>>(istream&,matrice&); /*supraincarcarea operatorului
'extragere din flux' pentru citirea elementelor unei matrice */
friend ostream& operator<<(ostream&,matrice); /*supraincarcarea operatorului
'insertie in flux' pentru afisarea elementelor unei matrice */
matrice operator+(matrice&); /* supraincarcarea operatorului '+' pentru
adunarea a doua matrice */
matrice operator-(); /* supraincarcarea operatorului '-' pentru
determinarea opusei unei matrice */
matrice operator-(matrice&); /* supraincarcarea operatorului '-' pentru
diferenta a doua matrice */
matrice operator~(); // transpusa unei matrice
};

/* constructor de initializare cu parametri */


inline matrice::matrice(int i,int j): m(i), n(j)
{
mat=new int[m*n]; /* alocam memorie suficienta in zona HEAP pentru pastrarea
unui tablou m*n elemente intregi */
}

/* supraincarcarea operatorului special 'apel de functie' pentru determinarea unui


element al matricei dintr-o anumita pozitie, pozitie data ca parametru */
int* matrice::operator()(int i,int j)
{
return mat+i*n+j; /* adresa elementului de pe pozitia de linie i si coloana j a
unei matrice */
}

/* supraincarcarea operatorului 'extragere din flux' pentru citirea elementelor unei


matrice */
istream& operator>>(istream& x,matrice& a)
{
for(int i=0;i<a.m;i++)
for(int j=0;j<a.n;j++)
{
cout<<"\telem["<<i+1<<"]["<<j+1<<"]= ";
x>>*a(i,j); // apel al operatorului '()' supraincarcat
}
return x;
}

/* supraincarcarea operatorului 'insertie in flux' pentru afisarea elementelor unei


matrice */
ostream& operator<<(ostream& x,matrice a)
{
for(int i=0;i<a.m;i++)
{
for(int j=0;j<a.n;j++)
x<<setw(6)<<*a(i,j);
x<<endl;
}
return x;
}

/* supraincarcarea operatorului '+' pentru adunarea a doua matrice */


matrice matrice::operator+(matrice& a)
{
matrice b(a.m,a.n); //sau matrice b(m,n);
for(int i=0;i<b.m;i++)
for(int j=0;j<b.n;j++)
*b(i,j)=*a(i,j)+*(*this)(i,j);
return b;
}

/* supraincarcarea operatorului '-' pentru determinarea opusei unei matrice */


matrice matrice::operator-()
{
matrice a(m,n);
for(int i=0;i<a.m;i++)
for(int j=0;j<a.n;j++)
*a(i,j)=-*(*this)(i,j);
return a;
}

/* supraincarcarea operatorului '-' pentru diferenta a doua matrice */


matrice matrice::operator-(matrice& a)
{
return a+(-(*this));
}

/* supraincarcarea operatorului '~' pentru transpusa unei matrice */


matrice matrice::operator~()
{
matrice a(n,m);
for(int i=0;i<a.m;i++)
for(int j=0;j<a.n;j++)
*a(i,j)=*(*this)(j,i);
return a;
}

//Exemplu.cpp

#include"Matrice.h"

int main()
{
int m,n; // m - nr de linii, n - nr de coloane

cout<<"Dati dimensiunea matricelor:\n";


cout<<"\tnumarul de linii: ";
cin>>m;
cout<<"\tnumarul de coloane: ";
cin>>n;
matrice a(m,n),b(m,n); // apel al constructorului de initializare cu parametri

cout<<"Citim matricea A:\n";


cin>>a; // apel al functiei ce supraincarca operatorul '>>'
cout<<"Citim matricea B:\n";
cin>>b;

cout<<endl<<"Dati o tasta ptr. a continua...";


cin.get();
system("cls");

cout<<"Afisam matricea A:\n";


cout<<a; // apel al functiei ce supraincarca operatorul '<<'
cout<<"Afisam matricea B:\n";
cout<<b;

cout<<endl<<"Dati o tasta ptr. a continua...";


cin.get();
system("cls");

cout<<"Afisam A+B:\n";
cout<<a+b; // apel al functiilor ce supraincarca operatorii '+' si '<<'
cout<<"Afisam expresia A - B:\n";
cout<<a-b;

cout<<"Afisam transpusa A:\n"<<~a;


cout<<"Afisam transpusa B:\n"<<~b;

system("pause");
return (0);
}

4. Multimile
#include<iostream>
using namespace std;
class multime
{
int n;
int *m;
public:
multime(int x=0);
int apartenenta(int, int);
void citire(char*);
void afisare(char *);
multime operator-(multime); //diferenta
multime operator*(multime); //intersectia
multime operator+(multime); //reuniunea
};

inline multime::multime(int x) :n(x)


{
m = new int[n];
if(!m)
{
cout<<"Eroare la alocare";
}
}

int multime::apartenenta(int x, int poz)


{
int ok;
int i;
ok = 0;
for (i = 0; i<poz&& !ok; i++)
if (m[i] == x)
ok = 1;
return ok;
}

void multime::citire(char *c)


{
int i = 0;
cout<<"\tdati elementele multimii:\n";
cout<<"\t\telementul "<<c<<'['<<i + 1 <<"]=";
cin>> m[i];
i++;
while (i< n)
{
cout<<"\t\telementul "<<c<<'['<<i + 1 <<"]= ";
cin>> m[i];
if (apartenenta(m[i], i))
cout<<"\tValoarea introdusa exista deja in multime. Dati alta
valoare.\n";
else
i++;
}
}

void multime::afisare(char *c)


{
cout<<"Elementele multimii "<<c<<" sunt: ";
for (int i = 0; i< n; i++)
cout<< m[i] <<' ';
cout<<'\n';
}

multime multime::operator-(multime t)
{
multime d(n);
int dim = 0;
for (int i = 0; i< n; i++)
if(!t.apartenenta(m[i], t.n))
d.m[dim++] = m[i];
d.n = dim;
return d;
}

multime multime::operator*(multime t)
{
multime i(n <t.n ? n : t.n);
int dim = 0;
for (int j = 0; j < n; j++)
if (t.apartenenta(m[j], t.n))
i.m[dim++] = m[j];
i.n = dim;
return i;
}

multime multime::operator+(multime t)
{
multime r(n + t.n);
int dim = 0;
for (int i = 0; i< n; i++)
r.m[dim++] = m[i];
for (int j = 0; j <t.n; j++)
if(!(*this).apartenenta(t.m[j], n))
r.m[dim++] =t. m[j];
r.n = dim;
return r;
}

int main()
{
int x;
cout<<"Introduceti date pentrumultimea A\n";
cout<<"\tdati dimensiunea: ";
cin>> x;
multime a(x);
a.citire("A");
a.afisare("A");

cout<<"Introduceti date pentru multimea B\n";


cout<<"\tdati dimensiunea: ";
cin>> x;
multime b(x);
b.citire("B");
b.afisare("B");

multime d;
d = a-b;
d.afisare("A-B");

multime i;
i= a*b;
i.afisare("A intersectat cu B");

multime r;
r = a + b;
r.afisare("A reunit cu B");

system("pause");
return 0;
}

5. Numarul complex

#include<iostream>
#include<iomanip> /*biblioteca folosita pentru manipulatorii cu parametru, in
cazul acestei aplicatii: functia setprecision*/

using namespace std;


class complex
{
float a,b; //in 'a' memoram partea reala, in 'b' memoram partea imaginara
public:
complex(float=0,float=1); //constructor de initializare cu parametri
float& retre(); //returneaza partea reala
float& retim(); //returneaza partea imaginara
complex operator+(complex&); //adunarea a doua numere complexe
complex operator-(); //negativul (opusul) unui numar complex
complex operator-(complex&); /*diferenta intre doua numere complexe*/
complex operator~(); //conjugatul unui numar complex
complex operator*(complex&); //produsul a doua numere complexe
float operator!(); //modulul unui numar complex
complex operator *(float); //multiplicarea cu un scalar
friend complex operator*(float,complex&); /*operatia inversa celei
anterioare, adica, scalar inmultit cu nr. complex*/
friend istream& operator>>(istream&,complex&); /*supraincarcarea
operatorului de extragere din flux ptr. citirea unui nr. complex*/
friend ostream& operator<<(ostream&,complex); /*supraincarcarea
operatorului de insertie in flux ptr. afisarea unui nr. complex*/
};

inline complex::complex(float x,float y)


{
a=x;
b=y;
}

inline float& complex::retre()


{
return a;
}

inline float& complex::retim()


{
return b;
}

complex complex::operator+(complex& z)
{
complex r;
r.a=a+z.a;
r.b=b+z.b;
return r;
}

complex complex::operator-()
{
complex r;
r.a=-a;
r.b=-b;
return r;
}
complex complex::operator-(complex& z)
{
return (*this)+(-z); /*relatie intre obiectul curent si cel transmis ca
parametru, operatorii din relatie fiind cei supraincarcati
prin functiile anterioare*/
}

complex complex::operator~()
{
complex r;
r.a=a;
r.b=-b;
return r;
}

complex complex::operator*(complex& z)
{
complex r;
r.a=a*z.a-b*z.b;
r.b=a*z.b+b*z.a;
return r;
}

float complex::operator!()
{
return sqrt(pow(a,2)+pow(b,2));
}

complex complex::operator*(float x)
{
complex r;
r.a=x*a;
r.b=x*b;
return r;
}

complex operator*(float x, complex& z)


{
return z*x; //operator supraincarcat anterior
}

istream& operator>>(istream& c, complex& z)


{
cout<<"\tdati partea reala: ";
c>>z.a;
cout<<"\tdati partea imaginara: ";
c>>z.b;
return c;
}

ostream& operator<<(ostream& c, complex z)


{
c<<setprecision(2)<<z.a;
if(z.b>=0)
c<<setiosflags(ios::showpos)<<z.b<<"*i\n";
else
c<<z.b<<"*i\n";
c<<resetiosflags(ios::showpos);
return c;

int main()
{
complex z1,z2;

//citirea celor doua nr. complexe


cout<<"Dati nr. complex z1\n";
cin>>z1;
cout<<"Dati nr. complex z2\n";
cin>>z2;

cout<<'\n';

//afisarea celor doua nr. complexe


cout<<"z1="<<z1;
cout<<"z2="<<z2;

cout<<'\n';

//operatii pe nr. complexe


cout<<"z1+z2="<<z1+z2;
cout<<"z1-z2="<<z1-z2;
cout<<"z1*z2="<<z1*z2;
cout<<"z1 conjugat="<<~z1;
cout<<"z2 conjugat="<<~z2;
cout<<"|z1|="<<setprecision(2)<<!z1<<'\n';
cout<<"|z2|="<<setprecision(2)<<!z2<<'\n';

system("pause");
return (0);
}

6. Numarul rational
#include<iostream>
using namespace std;

class rational
{
int a,b; //a=numaratorul, b=numitorul
int cmmdc(int,int); //cmmdc-ul a doua numere intregi
void ireductibil(); //aducerea unei fractii intr-o forma ireductibila
public:
rational(int=0,int=1); //constructor prin parametri
rational(const rational&); //constructor prin copiere
int& numarator(); //extragerea numaratorului
int& numitor(); //extragerea numitorului
//citirea unui numar rational
friend istream& operator>>(istream&,rational&); //cin>>r;
//afisarea unui numar rational
friend ostream& operator<<(ostream&,rational); //cout<<r;
rational operator+(rational&); //r1+r2
rational operator-(rational&); //r1-r2
rational operator*(rational&); //r1*r2
rational operator*(int); //r*7 (amplificarea unei fractii)
friend rational operator*(int,rational&); //(-3)*r
rational operator/(rational&); //r1/r2
private:
rational operator-(); //-r1 (opusul)
rational operator!(); //1/r (inversul)
};

inline int rational::cmmdc(int x, int y)


{
if(x==y) return x;
if(x>y) return cmmdc(x-y,y);
return cmmdc(x,y-x);
}

inline void rational::ireductibil()


{
if(!a)
{
b=1;
return; //se face iesire fortata din functie
}
if(b<0)
{
a=-a;
b=-b;
}
if(abs(a)!=1 && b!=1)
{
int d=cmmdc(abs(a),b);
a/=d;
b/=d;
}
}

inline rational::rational(int x,int y):a(x),b(y){}

inline rational::rational(const rational& r):a(r.a),b(r.b){}

int& rational::numarator()
{
return a;
}

int& rational::numitor()
{
return b;
}

istream& operator>>(istream& x, rational& r)


{
cout<<"\tintroduceti numaratorul: ";
x>>r.a;
do{
cout<<"\tintroduceti numitorul: ";
x>>r.b;
}while(r.b==0);
r.ireductibil();
return x;
}

ostream& operator<<(ostream& x, rational r)


{
if(r.b==1)
x<<r.a<<'\n';
else
x<<r.a<<'/'<<r.b<<'\n';
return x;
}

rational rational::operator+(rational& r)
{
rational t;
t.a=a*r.b+b*r.a;
t.b=b*r.b;
t.ireductibil();
return t;
}

rational rational::operator-()
{
rational t;
t.a=-a;
t.b=b;
return t;
}

rational rational::operator-(rational& r)
{
rational t;
t=(*this)+(-r);
t.ireductibil();
return t;
}

rational rational::operator*(rational& r)
{
rational t;
t.a=a*r.a;
t.b=b*r.b;
t.ireductibil();
return t;
}

rational rational::operator*(int x)
{
rational t;
t.a=a*x;
t.b=b*x;
return t;
}

rational operator*(int x, rational& r)


{
return r*x;
}

rational rational::operator!()
{
rational t;
t.a=b;
t.b=a;
return t;
}

rational rational::operator/(rational& r)
{
rational t;
t=(*this)*(!r);
t.ireductibil();
return t;
}

int main()
{
rational r1,r2;

//citirea si afisarea celor doua numere rationale


cout<<"Dati nr. rational R1\n";
cin>>r1;
cout<<"Dati nr. rational R2\n";
cin>>r2;
cout<<"Nr. rational R1: "<<r1;
cout<<"Nr. rational R2: "<<r2;

//operatii de numere rationale


cout<<"Nr. rational R1+R2: "<<r1+r2;
cout<<"Nr. rational R1-R2: "<<r1-r2;
cout<<"Nr. rational R1*R2: "<<r1*r2;
if(!r2.numarator()) //r2.a==0
cout<<"Nr. rational R1/R2: operatie imposibila\n";
else
cout<<"Nr. rational R1/R2: "<<r1/r2;

system("pause");
return (0);
}

S-ar putea să vă placă și