Sunteți pe pagina 1din 7

Ministerul Educaţiei, Culturii și Cercetării al Republicii Moldova

Universitatea Tehnică a Moldovei

Departamentul Informatică și Ingineria Sistemelor

RAPORT
Lucrarea de laborator nr.3
la Programarea Calculatoarelor
Varianta 2

A efectuat: st. gr.

A verificat:

Chişinău -2024
LUCRARE DE LABORATOR NR. 3

Tema: Moştenirea şi compoziţia


Scopul lucrării:
 studierea moştenirii, avantajele şi dezavantajele
 studierea compoziţiei
 studierea regulilor de definire a moştenirii şi compoziţiei
 studierea formelor de moştenire
 studierea iniţializatorilor
 principiul de substituţie
 moştenire şi compoziţie
Noţiuni de bază:
Derivarea permite definirea într-un mod simplu, eficient şi flexibil a unor clase
noi prin adăugarea unor funcţionalităţi claselor deja existente, fără să fie necesară
reprogramarea sau recompilarea acestora. Clasele derivate exprimă relaţii ierarhice
între conceptele pe care acestea le reprezintă şi asigură o interfaţă comună pentru
mai multe clase diferite. Moştenirea poate fi abordată din două puncte de vedere: al
elaboratorului şi al utilizatorului clasei. Din punctul de vedere al elaboratorului,
moştenirea abordează comportarea şi proprietăţile clasei derivate ca extensie a
proprietăţilor clasei de bază. Din punct de vedere al utilizatorului – moştenirea
semnifică existenţa unui şir de clase parţial intershimbabile cu o interfaţă unică.
(Inginerii TI şi inginerii mecanici sunt ambii, în primul rînd, ingineri). Avantajele
moştenirii: - micşorarea volumului de cod şi utilizarea lui repetată, - micşorarea
numărului de erori şi a preţului de cost, - interfaţă unică şi substituire, - mărirea
vitezei de elaborare. Un neajuns al moştenirii ar fi o oarecare micşorare a vitezei de
executare a codului. Totuşi eficienţa nu trebuie să contrazică avantajele, deoarece
cheltuielile reale nu sunt esenţiale, ele fiind evitate parţial prin utilizarea funcţiilor.
Definirea şi utilizarea moştenirii O clasă care asigură proprietăţi comune mai
multor clase se defineşte ca o clasă de bază. O clasă derivată moşteneşte de la una
sau mai multe clase de bază toate caracteristicile acestora, cărora le adaugă alte
caracteristici noi, specifice ei.
Sarcina:Varianta 2
а) Să se creeze clasa student, care are un nume, specialitate, anul de învăţământ şi
balul mediu. Determinaţi funcţia de definire, schimbare a datelor şi de comparare.
Pentru setarea câmpurilor textuale să se folosească operatorul new. Determinaţi
constructorii, destructorul şi alte funcţii necesare. Creaţi clasa derivată student-
diplomant, pentru care este definită tema de diplomă. De asemenea, este necesar de
definit toate funcţiile necesare.
b) Să se creeze clasa camera, care conţine suprafaţă. Determinaţi constructorii şi
metodele de acces. Creaţi clasa apartament cu o odaie, care conţine o odaie şi o
bucătarie (suprafaţa ei), etajul (camera este în clasa apartament cu o odaie).
Determinaţi constructorii, metodele de acces. Definiţi clasa derivată a
apartamentelor cu o odaie cu adresă (un câmp adăugător - adresa). Determinaţi
constructorii, destructorul şi fluxul de ieşire.
Codul programului (a):
#include <iostream> ~Student() {
#include <cstring> delete[] nume;
delete[] specialitate;
class Student { }
protected:
char* nume; void definireDate(const char* nume, const
char* specialitate, int an, float balMediu) {
char* specialitate;
delete[] this->nume;
int an;
delete[] this->specialitate;
float balMediu;

this->nume = strdup(nume);
public:
this->specialitate = strdup(specialitate);
// Constructori, destructor și alte funcții
this->an = an;
Student(const char* nume, const char*
specialitate, int an, float balMediu) this->balMediu = balMediu;
: nume(strdup(nume)), }
specialitate(strdup(specialitate)), an(an),
balMediu(balMediu) {}
bool operator==(const Student& other) const
{
Student(const Student& other)
return (strcmp(nume, other.nume) == 0 &&
: nume(strdup(other.nume)),
strcmp(specialitate, other.specialitate)
specialitate(strdup(other.specialitate)),
== 0 &&
an(other.an), balMediu(other.balMediu) {}
an == other.an &&
balMediu == other.balMediu); delete[] temaDiploma;
} }

friend std::ostream& void definireTemaDiploma(const char*


operator<<(std::ostream& os, const Student& temaDiploma) {
student);
delete[] this->temaDiploma;
};
this->temaDiploma =
strdup(temaDiploma);
std::ostream& operator<<(std::ostream& os, }
const Student& student) {
os << "Nume: " << student.nume << "\n";
bool operator==(const StudentDiplomant&
os << "Specialitate: " << student.specialitate other) const {
<< "\n";
return (static_cast<const Student&>(*this)
os << "An: " << student.an << "\n"; == static_cast<const Student&>(other) &&
os << "Bal mediu: " << student.balMediu << strcmp(temaDiploma,
"\n"; other.temaDiploma) == 0);
return os; }
}
friend std::ostream&
operator<<(std::ostream& os, const
class StudentDiplomant : public Student {
StudentDiplomant& diplomant);
private:
};
char* temaDiploma;

std::ostream& operator<<(std::ostream& os,


public: const StudentDiplomant& diplomant) {

// Constructori, destructor și alte funcții os << static_cast<const


Student&>(diplomant);
StudentDiplomant(const char* nume, const
char* specialitate, int an, float balMediu, const os << "Tema de diploma: " <<
char* temaDiploma) diplomant.temaDiploma << "\n";

: Student(nume, specialitate, an, balMediu), return os;


temaDiploma(strdup(temaDiploma)) {}
}

StudentDiplomant(const StudentDiplomant&
int main() {
other)
// Exemplu de utilizare a claselor
: Student(other),
temaDiploma(strdup(other.temaDiploma)) {} Student student1("John Doe", "Informatica",
2, 9.5);
Student student2 = student1; // Apelul
~StudentDiplomant() {
constructorului de copiere
std::cout << "Student 1:\n" << student1 << std::cout << "Diplomant 2:\n" << diplomant2
std::endl; << std::endl;
std::cout << "Student 2:\n" << student2 << diplomant2.definireTemaDiploma("Sisteme
std::endl; integrate de control");
student2.definireDate("Alice Wonderland", std::cout << "Diplomant 2 dupa schimbare:\n"
"Matematica", 3, 8.7); << diplomant2 << std::endl;
std::cout << "Student 2 dupa schimbare:\n" if (diplomant1 == diplomant2) {
<< student2 << std::endl;
std::cout << "Diplomantii au aceleasi
StudentDiplomant diplomant1("Bob Builder", informatii." << std::endl;
"Inginerie", 4, 9.0, "Implementarea unui robot
} else {
autonom");
std::cout << "Diplomantii nu au aceleasi
StudentDiplomant diplomant2 = diplomant1;
informatii." << std::endl;
std::cout << "Diplomant 1:\n" << diplomant1
}
<< std::endl;
return 0;}

Rezultatele programului (a):


Codul programului (b): #include <iostream>
#include <string> class ApartamentCuAdresa : public
ApartamentCuOdaie {
class Camera {
private:
private:
std::string adresa;
float suprafata;
public:
public:
// Constructori
// Constructori
ApartamentCuAdresa(float suprafataOdaie,
Camera() : suprafata(0.0) {}
float suprafataBucatarie, int etaj, const
Camera(float suprafata) : suprafata(suprafata) std::string& adresa)
{}
: ApartamentCuOdaie(suprafataOdaie,
// Metode de acces suprafataBucatarie, etaj), adresa(adresa) {}

float getSuprafata() const { // Destructor

return suprafata; ~ApartamentCuAdresa() {

} // Daca ar fi necesar, ar putea fi


implementat un destructor specific
};
}
class ApartamentCuOdaie {
// Supraincarcare operator <<
private:
friend std::ostream&
Camera odaie; operator<<(std::ostream& os, const
float suprafataBucatarie; ApartamentCuAdresa& apartament);};

int etaj; std::ostream& operator<<(std::ostream& os,


const ApartamentCuAdresa& apartament) {
public:
os << "Apartament cu o odaie si adresa:\n";
// Constructori
os << " Suprafata totala: " <<
ApartamentCuOdaie(float suprafataOdaie, apartament.getSuprafataTotala() << " metri
float suprafataBucatarie, int etaj) patrati\n";
: odaie(suprafataOdaie), os << " Etaj: " << apartament.getEtaj() << "\
suprafataBucatarie(suprafataBucatarie), n";
etaj(etaj) {}
os << " Adresa: " << apartament.adresa << "\
// Metode de acces n";
float getSuprafataTotala() const { return os;}
return odaie.getSuprafata() + int main() {
suprafataBucatarie;}
// Exemplu de utilizare
int getEtaj() const {
ApartamentCuAdresa apartament1(20.0, 15.0,
return etaj; 2, "Strada Principala, Nr. 10");
} std::cout << apartament1 << std::endl;
}; return 0;}
Rezultatele programului (b):

Concluzie:
Aceste două coduri oferă exemple de implementare a claselor în C++,
demonstrând concepte precum moștenirea, compoziția și suprascrierea
operatorilor. În primul cod, am creat o clasă Vector pentru manipularea vectorilor
de tip long, iar în al doilea cod, am definit trei clase, Camera, ApartamentCuOdaie,
și ApartamentCuAdresa, pentru a modela structura unui apartament cu o odaie,
inclusiv variantele cu sau fără adresă.
Principalele puncte de învățat din aceste exemple includ:
1. Moștenirea și Compoziția: În ambele coduri, am utilizat moștenirea
(ApartamentCuAdresa este o clasă derivată a ApartamentCuOdaie) și compoziția
(ApartamentCuOdaie conține un obiect de tip Camera). Aceste concepte ajută la
organizarea și reutilizarea codului.
2. Constructori și Destructori: Am definit constructori pentru inițializarea
obiectelor și destructori pentru eliberarea resurselor atunci când aceste obiecte sunt
distruse.
3. Suprascrierea Operatorilor: În special, am suprascris operatorul << pentru a
permite afișarea informațiilor despre obiecte într-un mod ușor de înțeles.
4. Funcții Prietene și Metode: Am folosit funcții prietene pentru a permite
suprascrierea operatorului << să acceseze membrii privați ai claselor. Metodele de
acces au fost definite pentru a oferi acces controlat la membrii privați ai claselor.
Aceste exemple ar trebui să servească ca bază pentru înțelegerea practică a
conceptelor de programare orientată pe obiect în limbajul C++. De asemenea, ar
trebui să fie adaptate și extinse pentru a satisface cerințele specifice ale proiectelor
sau aplicațiilor pe care le dezvoltați.

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