Documente Academic
Documente Profesional
Documente Cultură
RAPORT
Lucrare de laborator nr. 2
Varianta: 8
Chişinău 2011
1 Scopul şi sarcina lucrării
Scopul lucrării:
Sarcina lucrării:
а) Să se creeze clasa Date – dată cu cîmpurile: zi(1-28..31), lună(1-12), an (numere întregi). Să se
definească constructorii; funcţiile membru de setare a zilei, lunii şi anului; funcţiile membru de returnare
a zilei, lunii, anului; funcţiile de afişare: afişare tip „ 6 iunie 2004” şi afişare tip „6.06.2004”. Funcţiile de
setare a cîmpurilor clasei trebuie să verifice corectitudinea parametrilor primiţi.
b) Să se creeze clasa Matrix – matrice. Clasa conţine pointer spre int, 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.
2 Indicaţii teoretice
Una din cele mai răspîndite erori de programare (în orice limbaj) constă în utilizarea obiectelor
fără iniţializare anterioară, aşa precum nu toate limbajele asigură iniţializare automată. Desigur, poate
fi definită funcţia de iniţializare şi de distrugere a obiectului:
class Book{
char *author;
int year;
int pages;
public:
void Init(char*, int, int);
2
void Destroy();
};
void Book::Init(char* a, int y, int p){
author = new char[strlen(a)+1];
strcpy(author,a);
year=y;
pages=p;
}
void Book::Destroy(){
delete[] author;
}
În acest exemplu, însă, nimeni nu garantează că iniţializarea va avea loc, sau că va fi eliberată
memoria alocată. Alt neajuns al exemplului dat constă în pericolul scurgerii de memorie, deoarece
funcţia de iniţializare poate fi apelată de nenumărate ori. De asemenea se poate bloca sistemul din
cauza utilizării eronate a memoriei dinamice, motivul fiind apelul funcţiei Destroy fără iniţializare.
Pentru a evita această eroare, C++ asigură mecanismul de iniţializare automată pentru clasele
definite de utilizator – constructorul clasei. Iar pentru operaţiile de distrugere – destructorul clasei.
Constructorul – este o funcţie membru specială, de acelaşi nume cu numele clasei, care se
apelează automat la crearea obiectului de tipul clasei. Constructorul nu returnează nici un rezultat,
chiar nici void. Compilatorul garantează apelarea unică a constructorului pentru un singur obiect.
Pentru un obiect local, destructorul se apelează cînd controlul programului iese din domeniul
lui (se iese din blocul în care este declarat). Obiectele dinamice nu pot fi distruse automat.
Distrugerea se realizează de către programator prin intermediul operatorului delete, care apelează,
propriu zis, destructorul.
class Book{
3
char *author;
int year;
int pages;
public:
Book(char*, int, int);
~Book();
};
Book::Book(char* a, int y, int p){
author = new char[strlen(a)+1];
strcpy(author,a);
year=y;
pages=p;
}
Book::~Book(){
delete[] author;
}
void main(){
Book b(“Stroustrup”,2000,890);
// Book b1; // încercarea de a crea obiectul fără apelul //constructorului duce la erori
Book* ptr = new Book(“Lippman”,1996, 1200);
Constructorul implicit – constructor fără parametri, sau constructor cu toţi parametrii impliciţi.
Constructorul de copiere – constructor care are ca parametru referinţă la obiectul clasei respective.
Constructorul de copiere poate avea şi alţi parametri care însă trebuie să fie impliciţi.
Constructorul de conversie a tipului - constructorul, care transformă un tip de obiect în altul.
4
Constructorul general – constructorul care nu corespunde categoriilor enumerate mai sus.
Fie exemplul:
class Book{
char *author;
int year;
int pages;
public:
Book(); // constructor implicit
Book(const Book&); // constructor de copiere
Book(const char*); // constructor de conversie a tipului
Book(char*, int, int); // constructor general
...
};
...
void main(){
Book b(“Stroustrup”,1997,890); // general
Book b1 = b, b11(b); // de copiere
Book b2 = “Stroustrup”, b21(“Bjarne”);
// de schimbare a tipului
Book b3; // implicit
}
Constructori generaţi de compilator. Interacţiunea lor cu constructorii definiţi de
utilizator
Prezenţa constructorilor nu este obligatorie. Se pot defini clase şi fără constructori. În acest caz,
compilatorul C++ generează în mod automat un constructor implicit şi de copiere.
Constructorul implicit generat nu realizează absolut nimic, iar constructorul de copiere generat
automat implică copierea bit cu bit, ceea ce nu întotdeauna este satisfăcător. În cazul definirii unui
constructor de către utilizator se generează automat numai constructorul de copiere.
2.4 Recomandări
Fiecare clasă trebuie să conţină constructori. Dacă clasa conţine elemente pointeri trebuie
neapărat să se supraîncarce constructorul de copiere, care se utilizează pentru crearea copiilor
obiectului, la apelul obiectului în funcţie. Motivul supraîncărcării constructorului de copiere constă în
5
necesitatea utilizării acţiunilor suplimentare în comparaţie cu algoritmul standard de copiere,
deoarece se poate întîmpla ca două obiecte diferite să refere una şi aceeaşi memorie, ceea ce poate
duce la pierderea informaţiei şi la erori în sistemul de operare.
strcpy(author, b.author);
year = b.year;
pages = b.pages;
6
3 Realizarea sarcinii
a) - introducem data, luna, anul în variabilele programului;
- controlăm corectitudinea datei spre lună, şi luna februarie spre anul bisect;
- afişăm data/luna/anul în 2 formate diferite.
b) - crearea a 2 matrice;
- funcţia de adunare/scădere a 2 matrice;
- funcţia de înmulţire a 2 matrice: M1 şi M2;
- funcţia de înmulţire a unei matrice cu un număr.
Concluzia
În urma efectuării acestui laborator m-am cunoscut cu clasele în C++, am cunoscut diferenţa dintre
structuri şi clase şi am căpătat cunoştinţe cu constructorii şi distructorii la clase. În acest fel lucrul cu
clasele sunt foarte comode şi rapide.
Bibliografia
7
Anexa A
Imagini din programa (a)
8
Figura A.3 – Afişarea datei în 2 formate
******************************************************************************************
9
Anexa B
Imagini din programa (b)
10
Figura B.3 – Înmulţirea a 2 matrice
11
Figura B.5 – Afişarea matricei
******************************************************************************************
12
Anexa C
Codul sursă (a)
#include <iostream>
#include <conio.h>
#include <stdlib.h>
using namespace std;
class Date{
int zi;
int luna;
int an;
int a[13];
public:
Date(){
a[1] = 31; // Ianuarie
a[2] = 28; // Februarie
a[3] = 31; // Martie
a[4] = 30; // Aprilie
a[5] = 31; // Mai
a[6] = 30; // Iunie
a[7] = 31; // Iulie
a[8] = 31; // August
a[9] = 30; // Septembrie
a[10] = 31; // Octombrie
a[11] = 30; // Noiembrie
a[12] = 31; // Decembrie
// Modifica numarul de zile pentru luna februarie in caz daca este an bisect sau nu
void febr(int bisect)
{
if(bisect == 1) a[2] = 29;
else a[2] = 28;
}
// Setarea/Modificarea datei
13
int set_date(int d, int m, int y)
{
if(control(d, m, y))
{
this->zi = d;
this->luna = m;
this->an = y;
return 1;
} else return 0;
}
case 2:
return "februarie";
break;
case 3:
return "martie";
break;
14
case 4:
return "aprilie";
break;
case 5:
return "mai";
break;
case 6:
return "iunie";
break;
case 7:
return "iulie";
break;
case 8:
return "august";
break;
case 9:
return "septembrie";
break;
case 10:
return "octombrie";
break;
case 11:
return "noiembrie";
break;
case 12:
return "decembrie";
break;
default:
return NULL;
break;
}
}
case 'm':
15
break;
case 'y':
break;
}
return 0;
}
};
Date D;
void menu()
{
cout << "1. Setarea datei" << endl;
if(D.ok()) cout << "2. Afisarea datei" << endl; // Afisarea in 2 formate
cout << "0. Iesire";
}
main()
{
char c;
system("cls");
menu();
c = getch();
switch(c)
{
case '0':
exit(1);
break;
16
cout << "Introduceti data(1..28..31): ";
cin >> d;
cout << endl << "Introduceti luna(1..12): ";
cin >> m;
cout << endl << "Introduceti anul(int): ";
cin >> y;
cout << endl << endl;
if(D.set_date(d, m, y))
{
cout << "Datele au fost salvate cu succes!";
getch();
main();
} else {
cout << "Formatul DATEI, LUNEI sau ANULUI este introdus GRESIT. " << endl << "Mai incercati
introducerea datelor.";
p = 1;
getch();
}
}
break;
default:
main();
break;
}
}
***************************************************************************************
17
Anexa D
Codul sursă (b)
#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()
{
this->error = 0;
this->p = NULL;
this->x = 0;
this->y = 0;
}
// Functia de copiere
void copy(Matrix &M)
{
18
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;
}
19
{
this->p[i][j] = valoarea;
}
delete p;
}
};
} 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.";
}
20
} 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.";
}
} 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";
}
/*void temp()
{
M1.setSize(3, 2);
M1.set(0, 0, 1);
M1.set(0, 1, 0);
M1.set(0, 2, 6);
M1.set(1, 0, 7);
M1.set(1, 1, 1);
M1.set(1, 2, -1);
M2.setSize(3, 3);
M2.set(0, 0, 2);
M2.set(0, 1, 0);
M2.set(0, 2, 4);
21
M2.set(1, 0, 3);
M2.set(1, 1, 7);
M2.set(1, 2, 5);
M2.set(2, 0, 1);
M2.set(2, 1, 4);
M2.set(2, 2, 8);
}*/
void menu()
{
cout << "Matricea M1:" << endl;
cout << "1. M1 - Crearea matricei patratice n x n" << endl;
cout << "2. M1 - Crearea matricei n x m" << endl;
if(M1.ok()) cout << "3. M1 - Afisarea/Redactarea elementelor matricei" << endl;
cout << endl << endl << "** Pentru a fi accesate toate meniurile," << endl << "incarcati cu elemente ambele
matrice M1, M2";
}
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;
M1.setSize(n, n);
cout << "Matricea patratica M1 a fost creata cu succes!";
getch();
main();
22
break;
case '2':
system("cls");
cout << "M1 - Crearea matricei patratice n x m" << endl << endl;
M1.setSize(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";
int c;
c = '0';
while(c != 27 && c != 13)
c = getch();
switch(c)
{
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;
23
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 '4':
system("cls");
cout << "M1 - Crearea matricei patratice n x n" << endl << endl;
M2.setSize(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);
cout << "Matricea " << n << " x " << m << " M2 a fost creata cu succes!";
getch();
main();
break;
case '6':
24
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");
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;
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;
25
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;
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;
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 << ": ";
26
cin >> nr;
cout << endl << "Matricea " << l << " in urma inmultirii cu " << nr << " este:" << endl;
inmultirea_nr(&M, nr);
getch();
main();
break;
case '0':
exit(1);
break;
default:
main();
break;
}
}
******************************************************************************************
27