Documente Academic
Documente Profesional
Documente Cultură
REFERAT
La Lucrare de laborator nr.2
la disciplina: Programarea in limbajul C++
Tema: Constructorul – funcţie de iniţializare a
obiectelor clasei
Varianta 10
A verificat: M. Balan
Chişinău 2014
1. Scopul lucrării:
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 conţine pointer spre float, numărul
de rînduri şi de coloane şi o variabilă – codul erorii. Să se definească constructorul
fără parametri (constructorul implicit), constructorul cu un parametru – matrice
pătrată şi constructorul cu doi parametri – matrice dreptunghiulară ş. a. Să se
definească funcţiile membru de acces: returnarea şi setarea valorii elementului (i,j).
Să se definească funcţiile de adunare şi scădere a două matrice; înmulţirea unei
matrice cu alta; înmulţirea unei matrice cu un număr. Să se testeze funcţionarea
clasei. În caz de insuficienţă de memorie, necorespondenţă a dimensiunilor
matricelor, depăşire 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 când 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.
Supraîncarcarea (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 întâlnirea 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 - cuvântul
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;}
3
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 cuvântul 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
când 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;
}
// 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];
}
int _x()
{
return this->x;
}
int _y()
{
return this->y;
}
delete p;
}
};
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;
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;
int i, j, nr;
cout << "Selectati elementul pentru
redactare (i, j):" << endl;
cout << "Linia i=";
cin >> i;
cout << endl << "Coloana j=";
cin >> j;
case '4':
system("cls");
cout << "M2 - Crearea matricei patratice n x n" << endl
<< endl;
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;
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;
int i, j, nr;
cout << "Selectati elementul pentru
redactare (i, j):" << endl;
cout << "Linia i=";
cin >> i;
cout << endl << "Coloana j=";
cin >> j;
case '7':
system("cls");
cout << "Adunarea matricelor M1 si M2" << endl <<
endl;
adunarea(&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;
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:
16
Inmultirea uneia din matrici cu un numar:
Întrebări de control:
17
1. Explicaţi termenul de iniţializare.
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 fără constructori?
Chiar daca constructorul nu este declarat, el este generat in mod
implicit de catre compilator.
5. Cîţi constructori poate conţine 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.
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 aceeaşi memorie.
#include<math.h>
#include<iostream.h>
#include<conio.h>
class complex
{public:
float x,y,m; //datele clasei
void display();
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();
}
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