Sunteți pe pagina 1din 20

Ministerul Educaiei al Republicii Moldova

Universitatea Tehnic a Moldovei


Catedra Automatica si Tehnologii Informationale
Ingineria Sistemelor Biomedicale

REFERAT
La Lucrare de laborator nr.2

la disciplina: Programarea in limbajul C++


Tema: Constructorul funcie de iniializare a
obiectelor clasei
Varianta 10

A efectuat:
Moroi Ion
A verificat:

st. gr. ISBM-131

M. Balan

Chiinu 2014
1. Scopul lucrrii:

Studierea principiilor de definire i utilizare a constructorilor


Studierea principiilor de definire i utilizare a destructorilor
Studierea tipurilor de constructori

2. Sarcina lucrarii:
S se creeze clasa Matrix matrice. Clasa conine pointer spre float, numrul
de rnduri i de coloane i o variabil codul erorii. S se defineasc constructorul
fr parametri (constructorul implicit), constructorul cu un parametru matrice
ptrat i constructorul cu doi parametri matrice dreptunghiular . a. S se
defineasc funciile membru de acces: returnarea i setarea valorii elementului (i,j).
S se defineasc funciile de adunare i scdere a dou matrice; nmulirea unei
matrice cu alta; nmulirea unei matrice cu un numr. S se testeze funcionarea
clasei. n caz de insuficien de memorie, necoresponden a dimensiunilor
matricelor, depire a limitei memoriei utilizate s se stabileasc codul erorii.
3. Indicatii teoretice:

Constructori
Constructorii sunt metode speciale care folosesc la crearea si initializarea
instantelor unei clase.

Programatorul poate defini un constructor.

In absenta altor definitii, clasei i se ataseaza in mod implicit un constructor.


Un astfel de constructor se numeste constructor implicit.

Constructorii impliciti nu au parametri

Constructorii impliciti nu se genereaza in cazul in care clasa are atasat un alt


constructor (asadar constructorii impliciti sunt constructori fara parametri generati
automat de limbaj daca programatorul nu si-a definit unul).

Constructorii au acelasi nume ca si clasa careia i apartin

Constructorii sunt apelati de fiecare data cnd se creaza noi instante ale
clasei.
class complex
{public:
float x,y,m; //datele clasei
void display();//metodele clasei
float modul();};
float complex::modul()
{return sqrt(x*x+y*y);
}
void complex::display()
{cout<<x<<"+"<<y<<"*i";}
Clasa nu are definit un constructor prin urmare este generat in mod automat un
constructor implicit care va permite declararea unor instante ale clasei astfel:
void main()
{ complex q1; //constructorul implicit permite
instantiarea clasei complex
complex *q=new complex;
cout<<q1.x<< <<q1.y; //afiseaza valori reziduale
2

cout<<endl<<q->x<< <<q->y; //afiseaza valori


reziduale
..
}
Cum am mai spus, programatorul isi poate defini constructori proprii. Constructorii
vor fi definiti ca niste functii fara tip, fara a se trece in dreptul constructorului
cuvantul cheie void. Constructorul va avea acelasi nume ca si al clasei careia ii
apartine.
O clasa poate avea mai multi constructori, care difera ntre ei prin numarul si tipul
parametrilor acestora. Acest lucru este posibil deoarece limbajul C++ permite
supradefinirea ( supraincarcarea=overloading) functiilor.
Suprancarcarea (supradefinirea) reprezinta posibilitatea de a atribui unui nume
mai multe semnificatii, care sunt selectate n functie de context. Practic, se pot
defini functii cu acelasi nume, dar cu liste de parametri diferite, ca numar si/sau ca
tipuri de parametri. n momentul apelului functiei, selectarea functiei adecvate se
face n urma compararii tipurilor parametrilor efectivi cu tipurile parametrilor
formali. De aceea, declararea unor functii cu acelasi nume si acelasi set de
parametri este ilegala si este semnalata ca eroare la compilare.
La ntlnirea declararii unui obiect, se apeleaza automat un constructor al clasei
respective. La fiecare instantiere a clasei se aloca memorie pentru datele membre.
Deci pentru fiecare obiect declarat se aloca memorie pentru datele membre ale
clasei. Functiile membru exista ntr-un singur exemplar pentru toate instantele
clasei.
Ordinea n care sunt apelati constructorii corespunde ordinii declararii obiectelor.
Proprietatile constructorilor:
Constructorii au acelati nume ca si numele clasei careia i apartin;
Nu ntorc nici o valoare (din corpul lor lipseste intructiunea return; n antetul
constructorilor nu se specifica niciodata - la tipul valorii returnate - cuvntul
cheie void);
Constructorii unei clase nu pot primi ca parametri instante ale unei clase, ci
doar pointeri sau referinte la instantele clasei respective;
Apelul constructorului se realizeaza la declararea unui obiect;
Adresa constructorilor nu este accesibila utilizatorului;
Constructorii nu pot fi metode virtuale (vor fi studiate ulterior);
n cazul n care o clasa nu are nici constructor declarat de catre programator,
compilatorul genereaza un constructor implicit, fara nici un parametru, cu
lista instructiunilor vida. Daca exista un constructor, compilatorul nu mai
genereaza constructorul implicit ;
Parametrii unui constructor nu pot fi de tipul definit de clasa al
carei
{cout<<endl<<"mesaj de la
constructor"<<endl;}

Destructori
Destructorii sunt metode ale claselor care actioneaza n sens invers,
complementar, fata de constructori. Constructorii sunt folositi pentru alocarea
memoriei, initializarea datelor membru sau alte operatii (cum ar fi, incrementarea
unui contor pentru instantele clasei). Constructorul este apelat n momentul
declararii obiectelor.
Destructorul elibereaza memoria alocata de constructori. Destructorul este apelat
automat, la iesirea din blocul n care este recunoscut acel obiect.
Proprietatile destructorilor
Destructorul are acelasi nume ca si clasa a caror metoda este;
Numele destructorului este precedat de semnul ~;
O clasa are un singur destructor;
Destructorul nu are parametri si nu returneaza nici o valoare (antetul nu
contine cuvntul cheie void, iar n corpul destructorului nu apare
instructiunea return;);
Daca programatorul nu a definit un destructor, compilatorul genereaza
automat un destructor pentru clasa respectiva;
Destructorii se apeleaza la ncheierea timpului de viata a obiectelor, n
ordine inversa apelurilor constructorilor;

Obiectele dinamice nu se distrug automat, deoarece doar programatorul stie


cnd nu mai este necesar un astfel de obiect.
Listningul programului

#include <iostream>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
using namespace std;
/*
Codurile erorilor:
1 - Insuficienta de memorie
2 - Necorespondenta a dimensiunilor matricelor
3 - Depasirea limitei memoriei utilizate
*/
class Matrix{
int **p;
int x; // Nr. coloanelor
int y; // Nr. rindurilor
int error; // Numarul erorii
public:
// Constructor implicit
Matrix()
{
4

this->error = 0;
this->p = NULL;
this->x = 0;
this->y = 0;
}
// Constructor cu un parametru, matrice patrata
Matrix(int x1)
{
this->x = x1;
this->y = x1;
this->error = 0;
this->p = NULL;
}
// Constructor cu 2 parametri, matrice dreptungiulara
Matrix(int x1, int y1)
{
this->x = x1;
this->y = y1;
this->error = 0;
this->p = NULL;
}
// Functia de copiere
void copy(Matrix &M)
{
this->x = M.x;
this->y = M.y;
error = M.error;
this->setSize(x, y);
this->p = NULL;
p = new int*[x];
for(int i=0; i<y; i++){
p[i] = new int[x];
}
for(int i=0; i<y; i++)
for(int j=0; j<x; j++)
this->p[i][j]=M.p[i][j];
}
// Returneaza 1 daca matricea este ca minim x si y diferit
de 0;
int ok()
{
if(this->x>0 && this->y>0) return 1;
else return 0;
}
// Returnarea valorii (i, j)
int gets(int i, int j)
{
return this->p[i][j];
5

}
//Formarea matricei
void setSize(int n, int m)
{
this->x = n;
this->y = m;
this->p = NULL;
p = new int*[x];
for(int i=0; i<y; i++){
p[i] = new int[x];
}
for(int i=0; i<y; i++)
for(int j=0; j<x; j++)
this->p[i][j]=0;
}
//Setarea valorilor matricei
void setMatrix(int n, int m)
{
int val=0;
for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
{
cout<<"Elementul "<<"("<<i <<
j<<")"<<"=";
cin>>val;
this->p[i][j]=val;
}
}
int _x()
{
return this->x;
}
int _y()
{
return this->y;
}
// Modificarea valorii (i, j), nr. linii = i; nr. coloanei =
j
void set(int i, int j, int valoarea)
{
this->p[i][j] = valoarea;
}
// Functia pentru afisarea matricei
void view()
{
for(int i=0; i<_y(); i++)
{
6

for(int j=0; j<_x(); j++)


cout << gets(i, j) << "\t";
cout << endl;
}
}
// Eliberarea memoriei, distructor
~Matrix()
{
for(int i=0; i<x; i++)
delete[] p[i];
delete p;
}
};
// Functia pentru adunarea a 2 matrice
void adunarea(Matrix *M1, Matrix *M2)
{
if(M1->_x() == M2->_x() && M1->_y() == M2->_y())
{
for(int i=0; i<M1->_y(); i++)
{
for(int j=0; j<M1->_x(); j++)
cout << (M1->gets(i, j)+M2->gets(i, j)) << "\t";
cout << endl;
}
} else cout << "Numarul de linii si coloane nu coincide" <<
endl << "Pentru a efectua operatia de adunare," << " este nevoie
sa coincida ambele n x m a ambelor matrice.";
}
// Functia pentru scaderea a 2 matrice
void scaderea(Matrix *M1, Matrix *M2)
{
if(M1->_x() == M2->_x() && M1->_y() == M2->_y())
{
for(int i=0; i<M1->_y(); i++)
{
for(int j=0; j<M1->_x(); j++)
cout << (M1->gets(i, j)-M2->gets(i, j)) << "\t";
cout << endl;
}
} else cout << "Numarul de linii si coloane nu coincide" <<
endl << "Pentru a efectua operatia de scadere," << " este nevoie
sa coincida ambele n x m a ambelor matrice.";
}
// Functia pentru inmultirea a 2 matrice
void inmultirea(Matrix *M1, Matrix *M2)
{
7

int sum;
if(M1->_x() == M2->_y())
{
for(int i=0; i<M1->_y(); i++)
{
for(int j=0; j<M1->_x(); j++)
{
sum = 0;
for(int k=0; k<M1->_x(); k++)
sum += M1->gets(i, k)*M2->gets(k, j);
cout << sum << "\t";
}
cout << endl;
}
} else cout << "Numarul de linii si coloane nu coincide" <<
endl << "Pentru a efectua operatia de inmultire," << " este
nevoie sa coincida numarul liniilor M1 cu numarul coloanelor din
M2";
}
// Functia pentru inmultirea unei matrice cu un numar
void inmultirea_nr(Matrix *M, int nr)
{
for(int i=0; i<M->_y(); i++)
{
for(int j=0; j<M->_x(); j++)
cout << M->gets(i, j)*nr << "\t";
cout << endl;
}
}
Matrix M1, M2;
void menu()
{
cout<<"
"<<endl;
cout << "
Matricea M1:" << endl;
cout<<"
"<<endl;
cout << "
1. M1 - Crearea matricei patratice
n x n" << endl;
cout<<"
"<<endl;
cout << "
2. M1 - Crearea matricei n x m" <<
endl;
cout<<"
"<<endl;
if(M1.ok()) cout << "
3. M1 Afisarea/Redactarea elementelor matricei" << endl;
cout<<"
"<<endl;
cout << "
Matricea M2:" << endl;
8

cout<<"
"<<endl;
cout << "
4. M2 - Crearea matricei patratice
n x n" << endl;
cout<<"
"<<endl;
cout << "
5. M2 - Crearea matricei n x m" <<
endl;
cout<<"
"<<endl;
if(M2.ok()) cout << "
6. M2 Afisarea/Redactarea elementelor matricei" << endl;
cout<<"
"<<endl;
cout << "
Functiile:" << endl;
cout<<"
"<<endl;
cout << "
7. Adunarea si Scaderea matricilor
M1 si M2" << endl;
cout<<"
"<<endl;
cout << "
8. Inmultirea matricei M1 cu M2" <<
endl;
cout<<"
"<<endl;
cout << "
9. Inmultirea unei matrice cu un
numar" << endl;
cout<<"
"<<endl;
cout << "
0. Iesire"<<endl;
cout<<"
"<<endl;
cout << endl << endl << "** Pentru a fi accesate toate
meniurile," << endl << "incarcati cu elemente ambele matrice M1,
M2";
}
int main()
{
system("cls"); //temp();
menu();
char c;
c = getch();
int n, m;
Matrix M;
switch(c)
{
case '1':
system("cls");
cout << "M1 - Crearea matricei patratice n x n" << endl
<< endl;
9

cout << "Introduceti valoarea n=";


cin >> n;
M1.setSize(n, n);
M1.setMatrix(n, n);
cout << "Matricea patratica M1 a fost creata cu
succes!";
getch();
main();
break;
case '2':
system("cls");
cout << "M1 - Crearea matricei patratice n x m" << endl
<< endl;
cout << "Introduceti nr. de coloane n=";
cin >> n;
cout << "Introduceti nr. de linii m=";
cin >> m;
M1.setSize(n, m);
M1.setMatrix(n, m);
cout << "Matricea " << n << " x " << m << " M1 a fost
creata cu succes!";
getch();
main();
break;
case '3':
if(M1.ok())
{
system("cls");
cout << "Afisarea matricei M1 (" << M1._x() << " x "
<< M1._y() << ")" << endl << endl;
M1.view();
int o;
o = 0;
while(!o)
{
o = 1;
cout << endl << endl << "Pentru redactarea
elementelor tastati ENTER, " << endl << "pentru a reveni in
meniul principal tastati ESC" <<endl;
int c;
c = '0';
while(c != 27 && c != 13)
c = getch();
switch(c)
10

{
case 13: // Enter
system("cls");
cout << "Redactarea elementelor matricei
M1:" << endl << endl;
cout << "Matricea M1: " << endl;
M1.view();
cout << endl << endl;
int i, j, nr;
cout << "Selectati elementul pentru
redactare (i, j):" << endl;
cout << "Linia i=";
cin >> i;
cout << endl << "Coloana j=";
cin >> j;
cout << endl << "Introduceti valoarea
elementului (" << i << ", " << j << ") = ";
cin >> nr;
if(i >= 0 && i < M1._x() && j >= 0 && j <
M1._y())
{
cout << endl << endl << "Valoarea a fost
salvat cu succes!" << endl;
M1.set(i, j, nr);
}
else cout << endl << endl << "EROARE!
Valoarea nu a fost salvata din cauza coordanatelor gresite" <<
endl;
cout << "Matricea arata in felul urmator: "
<< endl;
M1.view();
o = 0;
break;
case 27: // Esc
main();
break;
}
}
main();
} else main();
break;
case '4':
system("cls");
cout << "M2 - Crearea matricei patratice n x n" << endl
<< endl;
cout << "Introduceti valoarea n=";
cin >> n;
11

M2.setSize(n, n);
M2.setMatrix(n, n);
cout << "Matricea patratica M2 a fost creata cu
succes!";
getch();
main();
break;
case '5':
system("cls");
cout << "M2 - Crearea matricei patratice n x m" << endl
<< endl;
cout << "Introduceti nr. de coloane n=";
cin >> n;
cout << "Introduceti nr. de linii n=";
cin >> m;
M2.setSize(n, m);
M2.setMatrix(n, m);
cout << "Matricea " << n << " x " << m << " M2 a fost
creata cu succes!";
getch();
main();
break;
case '6':
if(M2.ok())
{
system("cls");
cout << "Afisarea matricei M2 (" << M2._x() << " x "
<< M2._y() << ")" << endl << endl;
M2.view();
int o;
o = 0;
while(!o)
{
o = 1;
cout << endl << endl << "Pentru redactarea
elementelor tastati ENTER, " << endl << "pentru a reveni in
meniul principal tastati ESC";
int c;
c = '0';
while(c != 27 && c != 13)
c = getch();
switch(c)
{
case 13: // Enter
system("cls");
12

cout << "Redactarea elementelor matricei


M2:" << endl << endl;
cout << "Matricea M1: " << endl;
M2.view();
cout << endl << endl;
int i, j, nr;
cout << "Selectati elementul pentru
redactare (i, j):" << endl;
cout << "Linia i=";
cin >> i;
cout << endl << "Coloana j=";
cin >> j;
cout << endl << "Introduceti valoarea
elementului (" << i << ", " << j << ") = ";
cin >> nr;
if(i >= 0 && i < M2._x() && j >= 0 && j <
M2._y())
{
cout << endl << endl << "Valoarea a fost
salvat cu succes!" << endl;
M2.set(i, j, nr);
}
else cout << endl << endl << "EROARE!
Valoarea nu a fost salvata din cauza coordanatelor gresite" <<
endl;
cout << "Matricea arata in felul urmator: "
<< endl;
M2.view();
o = 0;
break;
case 27: // Esc
main();
break;
}
}
main();
} else main();
break;
case '7':
system("cls");
cout << "Adunarea matricelor M1 si M2" << endl <<
endl;
adunarea(&M1, &M2);
cout << endl << endl << "Scaderea matricelor M1 si
M2" << endl << endl;
13

scaderea(&M1, &M2);
getch();
main();
break;
case '8':
system("cls");
cout << "Inmultirea matricelor M1 si M2" << endl <<
endl;
inmultirea(&M1, &M2);
getch();
main();
break;
case '9':
system("cls");
cout << "Inmultirea matricei cu un numar" << endl <<
endl;
cout << "Selectati matricea M1 sau M2 pentru
inmultire (1-2): ";
char l;
l = '0';
while(l != '1'&& l != '2')
l = getch();
switch(l)
{
case '1':
M.copy(M1);
break;
case '2':
M.copy(M2);
break;
}
int nr;
cout << endl << "Introduceti nr. de inmultire a
matricei " << l << ": ";
cin >> nr;
cout << endl << "Matricea " << l << " in urma
inmultirii cu " << nr << " este:" << endl;
inmultirea_nr(&M, nr);
getch();
main();
break;
14

case '0':
exit(1);
break;
default:
main();
break;

}}

Afisarea rezultatelor
Meniul:

Introducerea datelor:

15

Afisarea datelor:

Adunarea si scaderea matricilor:

16

Inmultirea uneia din matrici cu un numar:

Inmultirea primei matrice cu a doua:

ntrebri de control:
17

1. Explicai termenul de iniializare.


Initializarea unui obiect presupune si initializarea datelor membru ce descriu
starea acestuia; daca un constructor asociat tipului unei date membru are
parametrii avem nevoie de un mijloc pentru a specifica valorile acestora. Aici
intervine lista de initializarea a constructorului care este o secventa de
apeluri de constructori ai datelor membru si ai claselor din care clasa curenta
este derivata.
2. Ce cuvinte cheie se utilizeaz pentru definirea constructorului
i a destructorului?
3. Poate oare un constructor s returneze o valoare?
Constructorul nu poate returna valori.
4. Pot oare s existe clase fr constructori?
Chiar daca constructorul nu este declarat, el este generat in mod
implicit de catre compilator.
5. Ci constructori poate conine o clas? Dar destructori? De ce?
O clasa poate contine mai multi constructori, dar nu putem spune acelasi
lucru despre destructori, care intr-o clasa este exclusiv numai unul.
Constructorii sunt folositi pentru alocarea memoriei, initializarea datelor
membru sau alte operatii (cum ar fi, incrementarea unui contor pentru
instantele clasei). Constructorul este apelat n momentul declararii
obiectelor.
Destructorul elibereaza memoria alocata de constructori. Destructorul este
apelat automat, la iesirea din blocul n care este recunoscut acel obiect.

6. Enumerai tipurile de constructori?


Constructorul implicit constructor fr parametri, sau constructor cu toi
parametrii implicii.
Constructorul de copiere constructor care are ca parametru referin la
obiectul clasei respective. Constructorul de copiere poate avea i ali
parametri care ns trebuie s fie implicii.
Constructorul de conversie a tipului - constructorul, care transform un
tip de obiect n altul.
Constructorul general constructorul care nu corespunde categoriilor
enumerate mai sus.

7. Cum se apeleaz un constructor?


8. De ce este nevoie de definit un constructor de copiere?
Dac clasa conine elemente pointeri trebuie neaprat s se suprancarce
constructorul de copiere, care se utilizeaz pentru crearea copiilor obiectului,
la apelul obiectului n funcie. Motivul suprancrcrii constructorului de
copiere const n necesitatea utilizrii aciunilor suplimentare n comparaie
cu algoritmul standard de copiere, deoarece se poate ntmpla ca dou
obiecte diferite s refere una i aceeai memorie, ceea ce poate duce la
pierderea informaiei i la erori n sistemul de operare.
9. De ce este nevoie de definit un constructor de conversie a tipului?
Pentru evitarea erorilor dintre tipurile de variabile (float, double, int etc). De
asemenea constructorul de conversie nu permite conversia de la un tip
fundamental la un tip clasa.
18

10.
n ce cazuri se apeleaz constructorul de copiere? Care este
sintaxa apelului?
Daca clasa contine elemente pointeri.In cazul in care dou obiecte diferite
se refera la una i aceeai memorie.
#include<math.h>
#include<iostream.h>
#include<conio.h>
class complex
{public:
float x,y,m; //datele clasei
void display();
float modul(); //metoda clasei
complex(float xx=0, float yy=0)
{cout<<endl<<"mesaj de la constructorul cu parametri impliciti "<<endl;
x=xx;
y=yy;
}
complex(complex &ob)
//constructor de copiere
{ cout<<endl<<"operatie de copiere ";
x=ob.x;
y=ob.y;
}
};
float complex::modul()
{return sqrt(x*x+y*y);
}
void complex::display()
{cout<<endl<<x<<"+"<<y<<"*i";
cout<<endl;
}
void main()
{complex q1(1.2,1.3);
cout<<"q1=";
q1.display();
complex q2=q1; //se apeleaza constructorul de copiere
cout<<"q2=";
q2.display();
complex q3=complex(q1); //se apeleaza constructorul de copiere
cout<<"q3=";
q3.display();
getch();
19

clrscr();
}
11.

Ce sunt listele de iniializare (iniializatori)?


Initializarea unui obiect presupune si initializarea datelor membru ce
descriu starea acestuia; daca un constructor asociat tipului unei date
membru are parametrii avem nevoie de un mijloc pentru a specifica valorile
acestora. Aici intervine lista de initializarea a constructorului care este o
secventa de apeluri de constructori ai datelor membru si ai claselor din care
clasa curenta este derivata. Lista de initializare a constructorului urmeaza
imediat dupa lista de parametrii ai constructorului separata prin intermediul
delimitatorului ":" . Apelurile de constructori din cadrul listei de initializare
sunt separate prin ";"
12.
n care caz se definete obligatoriu constructorul implicit?
Cind constructorul nu a fost declarat in clasa de catre programator.

Concluzie:
In urma efectuarii acestei lucrari de laborator capatat cunostinte despre
modul de lucru cu clasele in limbajul c++, am capatat cunostinte despre
modul de formare a constructorilor si destructorilor unei clase.

20