MINISTERUL EDUCAŢIEI ȘI CERCETĂRII AL REPUBLICII MOLDOVA
UNIVERSITATEA TEHNICĂ A MOLDOVEI
FACULTATEA CALCULATOARE, INFORMATICĂ ŞI
MICROELECTRONICĂ DEPARTAMENTUL INFORMATICĂ ȘI INGINERIEA
SISTEMELOR
Raport
Lucrarea de laborator nr. 3
la disciplina “Programarea orientată pe obiecte”
A efectuat: Jalba Ion
st. gr. EA-231
A verificat: Mititelu Vitalie
Asistent universitar.
CHIŞINĂU 2024
Lucrarea de laborator nr. 3
Tema: Supraîncărcarea operatorilor
Scopul lucrării:
Studierea necesităţii supraîncărcării operatorilor;
Studierea sintaxei de definire a operatorilor;
Studierea tipurilor de operatori;
Studierea formelor de supraîncărcare;
Sarcina:
Varianta 4
а) Să se creeze clasa Date – data, care conţine cîmpurile: ziua, luna, anul. Să se definească
operatorii "+" şi "-" ca metode ale clasei, iar operatorii "++" şi "--" în ambele variante(prefixă şi
postfixă) ca funcţii prietene. Operatorul "+" trebuie să permită realizarea operaţiilor numai cu
variabilele de tip predefinit int (x=y+5). De prevăzut prelucrarea corectă a anilor bisecţi.
b) Să se creeze clasa List – coadă. Să se definească operatorii "+" – de adunare a listelor,
"=" – de atribuire ca metode ale clasei. Să se definească operatorii de comparare "==", "!=", "<",
">" ca funcţii prietene. Să se supraîncarce operatorii "<<" şi ">>" pentru ieşiri/intrări de obiecte,
precum şi pentru inserarea/eliminarea elementelor în/din coadă. Clasa trebuie să fie absolut
funcţională, adică să conţină toţi constructorii necesari şi destructorul. Pentru simplificarea
lucrului să se utilizeze clasa sau structura ListItem pentru reprezentarea elementelor listei spre
care referă List.
Codul programului:
#include <iostream>
#include <stdexcept>
#include <cstdlib>
using namespace std;
class Date {
private:
int ziua;
int luna;
int anul;
bool esteAnBisect(int an) const {
return (an % 4 == 0 && an % 100 != 0) || (an % 400 == 0);
}
int zileInLuna(int luna, int an) const {
static int zilePeLuna[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (luna == 2 && esteAnBisect(an)) {
return 29;
}
return zilePeLuna[luna - 1];
}
public:
Date(int zi = 1, int luna = 1, int an = 2000) : ziua(zi), luna(luna), anul(an) {}
Date operator+(int zile) const {
Date rezultat = *this;
[Link] += zile;
while ([Link] > [Link]([Link], [Link])) {
[Link] -= [Link]([Link], [Link]);
[Link]++;
if ([Link] > 12) {
[Link] = 1;
[Link]++;
}
}
return rezultat;
}
Date operator-(int zile) const {
Date rezultat = *this;
[Link] -= zile;
while ([Link] <= 0) {
[Link]--;
if ([Link] <= 0) {
[Link] = 12;
[Link]--;
}
[Link] += [Link]([Link], [Link]);
}
return rezultat;
}
friend Date& operator++(Date &data) {
data = data + 1;
return data;
}
friend Date operator++(Date &data, int) {
Date temp = data;
data = data + 1;
return temp;
}
friend Date& operator--(Date &data) {
data = data - 1;
return data;
}
friend Date operator--(Date &data, int) {
Date temp = data;
data = data - 1;
return temp;
}
void afiseaza() const {
std::cout << ziua << "/" << luna << "/" << anul << std::endl;
}
void citeste() {
std::cout << "Introduceti ziua: ";
std::cin >> ziua;
std::cout << "Introduceti luna: ";
std::cin >> luna;
std::cout << "Introduceti anul: ";
std::cin >> anul;
}
};
void afiseazaMeniuPunctA() {
std::cout << "\n--- Meniu Punct A ---\n";
std::cout << "1. Introduceti o noua data\n";
std::cout << "2. Adauga zile\n";
std::cout << "3. Scade zile\n";
std::cout << "4. Incrementare (++)\n";
std::cout << "5. Decrementare (--)\n";
std::cout << "6. Afisare data curenta\n";
std::cout << "x. Inapoi la meniul principal\n";
std::cout << "Alegeti o optiune: ";
}
void afiseazaMeniuPunctB() {
std::cout << "\n--- Meniu Punct B ---\n";
std::cout << "1. Introduceti elemente in lista 1\n";
std::cout << "2. Introduceti elemente in lista 2\n";
std::cout << "3. Elimina element din lista 1 la un index dat\n";
std::cout << "4. Elimina element din lista 2 la un index dat\n";
std::cout << "5. Afiseaza lista 1\n";
std::cout << "6. Afiseaza lista 2\n";
std::cout << "7. Concateneaza listele si afiseaza\n";
std::cout << "8. Compara listele\n";
std::cout << "x. Inapoi la meniul principal\n";
std::cout << "Alegeti o optiune: ";
}
void gestionarePunctA() {
Date data;
char optiuneA;
do {
afiseazaMeniuPunctA();
std::cin >> optiuneA;
switch (optiuneA) {
case '1': {
[Link]();
break;
}
case '2': {
int zile;
std::cout << "Introduceti numarul de zile de adaugat: ";
std::cin >> zile;
data = data + zile;
break;
}
case '3': {
int zile;
std::cout << "Introduceti numarul de zile de scazut: ";
std::cin >> zile;
data = data - zile;
break;
}
case '4': {
++data;
std::cout << "Data a fost incrementata.\n";
break;
}
case '5': {
--data;
std::cout << "Data a fost decrementata.\n";
break;
}
case '6': {
std::cout << "Data curenta este: ";
[Link]();
break;
}
case 'X':
case 'x':
cout << "Iesire din program." << endl;
break;
default:
cout << "Optiune invalida. Incercati din nou." << endl;
}
} while (optiuneA != 'x' && optiuneA != 'X');
}
// Structura pentru elementele listei
struct ListItem {
int value;
ListItem* next;
ListItem(int val) : value(val), next(nullptr) {}
};
// Clasa List - reprezentând o coadã
class List {
private:
ListItem* head;
ListItem* tail;
public:
List() : head(nullptr), tail(nullptr) {}
List(const List& other) : head(nullptr), tail(nullptr) {
ListItem* current = [Link];
while (current) {
enqueue(current->value);
current = current->next;
}
}
~List() {
while (head) {
dequeue();
}
}
List& operator=(const List& other) {
if (this != &other) {
while (head) {
dequeue();
}
ListItem* current = [Link];
while (current) {
enqueue(current->value);
current = current->next;
}
}
return *this;
}
List operator+(const List& other) const {
List result(*this);
ListItem* current = [Link];
while (current) {
[Link](current->value);
current = current->next;
}
return result;
}
void enqueue(int value) {
ListItem* newItem = new ListItem(value);
if (!tail) {
head = tail = newItem;
} else {
tail->next = newItem;
tail = newItem;
}
}
int dequeue() {
if (!head) {
throw out_of_range("Queue is empty");
}
int value = head->value;
ListItem* temp = head;
head = head->next;
delete temp;
if (!head) {
tail = nullptr;
}
return value;
}
bool removeAtIndex(int index) {
if (index < 0 || !head) return false;
if (index == 0) {
dequeue();
return true;
}
ListItem* current = head;
for (int i = 0; i < index - 1 && current->next; ++i) {
current = current->next;
}
if (!current->next) return false;
ListItem* temp = current->next;
current->next = temp->next;
if (temp == tail) tail = current;
delete temp;
return true;
}
friend bool operator==(const List& lhs, const List& rhs) {
ListItem* left = [Link];
ListItem* right = [Link];
while (left && right) {
if (left->value != right->value) return false;
left = left->next;
right = right->next;
}
return !left && !right;
}
friend bool operator!=(const List& lhs, const List& rhs) {
return !(lhs == rhs);
}
friend bool operator<(const List& lhs, const List& rhs) {
ListItem* left = [Link];
ListItem* right = [Link];
while (left && right) {
if (left->value < right->value) return true;
if (left->value > right->value) return false;
left = left->next;
right = right->next;
}
return !left && right;
}
friend bool operator>(const List& lhs, const List& rhs) {
return rhs < lhs;
}
friend ostream& operator<<(ostream& os, const List& list) {
ListItem* current = [Link];
while (current) {
os << current->value << " ";
current = current->next;
}
return os;
}
friend istream& operator>>(istream& is, List& list) {
int value;
is >> value;
[Link](value);
return is;
}
};
void gestionarePunctB() {
List list1, list2;
char optiuneB;
do {
afiseazaMeniuPunctB();
std::cin >> optiuneB;
switch (optiuneB) {
case '1': {
int numElements, value;
cout << "Cate elemente doriti sa introduceti in lista 1? ";
cin >> numElements;
cout << "Introduceti " << numElements << " element(e) pentru lista 1:" << endl;
for (int i = 0; i < numElements; ++i) {
cout << "Element " << i + 1 << ": ";
cin >> value;
[Link](value);
}
break;
}
case '2': {
int numElements, value;
cout << "Cate elemente doriti sa introduceti in lista 2? ";
cin >> numElements;
cout << "Introduceti " << numElements << " element(e) pentru lista 2:" << endl;
for (int i = 0; i < numElements; ++i) {
cout << "Element " << i + 1 << ": ";
cin >> value;
[Link](value);
}
break;
}
case '3': {
int index;
cout << "Introduceti indexul elementului de eliminat din lista 1: ";
cin >> index;
if ([Link](index)) {
cout << "Elementul de la indexul " << index << " a fost eliminat din lista 1." <<
endl;
} else {
cout << "Index invalid sau lista este goala." << endl;
}
break;
}
case '4': {
int index;
cout << "Introduceti indexul elementului de eliminat din lista 2: ";
cin >> index;
if ([Link](index)) {
cout << "Elementul de la indexul " << index << " a fost eliminat din lista 2." <<
endl;
} else {
cout << "Index invalid sau lista este goala." << endl;
}
break;
}
case '5': {
cout << "Lista 1: " << list1 << endl;
break;
}
case '6': {
cout << "Lista 2: " << list2 << endl;
break;
}
case '7': {
List concatenatedList = list1 + list2;
cout << "Listele concatenate: " << concatenatedList << endl;
break;
}
case '8': {
if (list1 == list2) {
cout << "Listele sunt egale." << endl;
} else if (list1 < list2) {
cout << "Lista 1 este mai mica decat lista 2." << endl;
} else if (list1 > list2) {
cout << "Lista 1 este mai mare decat lista 2." << endl;
} else {
cout << "Listele sunt diferite." << endl;
}
break;
}
case 'X':
case 'x':
cout << "Iesire din program." << endl;
break;
default:
cout << "Optiune invalida. Incercati din nou." << endl;
}
} while (optiuneB != 'x' && optiuneB != 'X');
}
void afiseazaMeniuPrincipal() {
std::cout << "\n--- Meniu Principal ---\n";
std::cout << "A. Gestionare Date (Punctul A)\n";
std::cout << "B. Functii suplimentare (Punctul B)\n";
std::cout << "x. Iesire\n";
std::cout << "Alegeti o optiune: ";
}
int main() {
char optiune;
do {
afiseazaMeniuPrincipal();
std::cin >> optiune;
switch (optiune) {
case 'A':
case 'a': {
gestionarePunctA();
break;
}
case 'B':
case 'b': {
gestionarePunctB();
break;
}
case 'X':
case 'x': {
std::cout << "Iesire din program.\n";
break;
}
default: {
std::cout << "Optiune invalida. Incercati din nou.\n";
break;
}
}
} while (optiune != '0');
return 0;
}
Testarea și verificarea programelor cu rezultatele obținute:
Punctul a)
1. Meniul principal:
2. Intr
odu
cere
date
pentru zi si afisarea zilei:
3. Increment
are si decrementare zi:
4. Punctul b:
Analiza rezultatelor si concluzii:
Supraîncărcarea operatorilor în C++ este o tehnică esențială care permite definirea unui
comportament specific pentru operatori atunci când aceștia sunt folosiți cu tipuri de date definite de
utilizator (de exemplu, clase). Prin această metodă, programatorii pot adapta și extinde
funcționalitățile operatorilor standard pentru a se potrivi cerințelor unor clase complexe, oferind un
cod mai intuitiv și mai ușor de utilizat.
Bibliografie:
1. [Link]
2. [Link] s
3. [Link]