Clase Si Obiecte: Review of C User's Defined Types: Struct
Clase Si Obiecte: Review of C User's Defined Types: Struct
O varianta mai buna: Implementam functii pentru diverse operatii asupra coordonatelor vectorului
(afisare, etc.);
#include <iostream>
using namespace std;
void print_Vector (int xS, int yS, int xE, int yE)
{
cout << "\nVector: ";
cout << "(" << xS << ", " << yS << ") --> ";
cout << "(" << xE << ", " << yE << ")" << endl;
}
void main () {
{
//...
int xStart = 1;
int yStart = 2;
int xEnd = 5;
int yEnd = 8;
//...
print_Vector (xStart, yStart,
//...
print_Vector (3, 8, 7, 1);
//...
}
xEnd, yEnd);
xEnd, yEnd);
//...
move_Vector (xStart, yStart, xEnd, yEnd, 2, 5, -1, 7);
cout << "\nNoua pozitie a vectorului: ";
print_Vector (xStart, yStart, xEnd, yEnd);
//...
}
Sau, si mai bine in acest caz: referinta constanta.... optimizare + protectie + lizibilitate !!
void print_Vector (const Vector &V)
{
cout << "\nVector: ";
cout << "(" << V.xStart << ", " << V.yStart << ") --> ";
cout << "(" << V.xEnd << ", " << V.yEnd << ")" << endl;
}
void main ()
{
//...
Vector V = {{1, 2}, {5, 8}}; // declaram si initializam vectorul V
//...
print_Vector (V); // "desenam" vectorul V
//...
set_Vector (V, -2, 3, 1, 7);
print_Vector (V); // "desenam" din nou vectorul V
//...
}
void set_Vector (Vector &Vect, const Point &pStart, const Point &pEnd)
{
cout << "\nInitializam vector...";
Vect.Start.x = pStart.x;
Vect.Start.y = pStart.y;
Vect.End.x = pEnd.x;
Vect.End.y = pEnd.y;
}
void print_Vector (const Vector &Vect)
{
cout << "\nVector: ";
cout << "(" << Vect.Start.x << ", " << Vect.Start.y << ")";
cout << " --> ";
cout << "(" << Vect.End.x << ", " << Vect.End.y << ")";
}
void main ()
{
//...
Vector V = {{1, 2}, {5, 8}}; // declaram si initializam vectorul V
//...
print_Vector (V); // "desenam" vectorul V
//...
set_Vector (V, -2, 3, 1, 7);
print_Vector (V); // "desenam" din nou vectorul V
//...
Point P1 = {1,2}, P2 = {-1, 18}; // declaram si intializam direct 2 Puncte
set_Vector (V, P1, P2); // initializam vectorul V
print_Vector (V); // "redesenam" vectorul
}
Modularizarea ne poate ajuta si mai mult: in sensul ca fiecare functie se ocupa de entitatea sa.
//*************************************************************************/
void set_Vector (Vector &Vect, int xStart, int yStart, int xEnd, int yEnd);
void set_Vector (Vector &Vect, const Point &pStart, const Point &pEnd);
void print_Vector (const Vector &Vect);
void set_Point (Point &P, int x, int y);
void print_Point (const Point& P);
void main ()
{
//...
Vector V = {{1, 2}, {5, 8}}; // declaram si initializam vectorul V
//...
print_Vector (V); // "desenam" vectorul V
//...
set_Vector (V, -2, 3, 1, 7);
print_Vector (V); // "desenam" din nou vectorul V
//...
Point P1 = {1,2}, P2 = {-1, 18}; // declaram si intializam direct 2 Puncte
set_Vector (V, P1, P2); // initializam vectorul V
print_Vector (V); // "redesenam" vectorul
}
//*************************************************************************/
void set_Vector (Vector &Vect, int xStart, int yStart, int xEnd, int yEnd)
{
cout << "\nInitializam vector...";
set_Point (Vect.Start, xStart, yStart);
set_Point (Vect.End, xEnd, yEnd);
}
void set_Vector (Vector &Vect, const Point &pStart, const Point &pEnd)
{
cout << "\nInitializam vector...";
set_Point (Vect.Start, pStart.x, pStart.y);
set_Point (Vect.End, pEnd.x, pEnd.y);
}
void print_Vector (const Vector &Vect)
{
cout << "\nVector: ";
print_Point (Vect.Start);
cout << " --> ";
print_Point (Vect.End);
}
//*************************************************************************/
void set_Point (Point &P, int x, int y)
{
cout << "\nInitializare punct cu coordonate noi: " << x << ", " << y << "...";
P.x = x;
P.y = y;
}
void print_Point (const Point& P)
{
cout << "(" << P.x << ", " << P.y << ")";
}
//*************************************************************************/
Cateva concluzii:
- Structurile ne ajuta pentru a putea modela diverse entitati
- Se poate lucra modular: modificarile de functionalitate (comportament) sau de structura
(date) se fac in puncte clare
- [Utilizarea referintelor la structuri aduce avantataje]
In general, o entitate are: structur (date) + comportament (functionalitate) !!
Problema:
- Datele sunt separate de comportament.
- Fiecare functie de lucru cu o entitate (comportament) nu apartine acelei entitati.
Lucreaza de la distanta cu structura (datele) entitatii.
- Solutia C++ (OOP): utilizarea claselor !!
// declaram 2 Puncte
// init P1
// init P2
void main ()
{
//...
Vector V;
V.set_Vector (1, 2, 5, 8);
//...
V.print_Vector ();
//...
V.set_Vector (-2, 3, 1, 7);
V.print_Vector ();
//...
// declaram vectorul
// initailizam vectorul
// "desenam" vectorul V
// "desenam" din nou vectorul V
// declaram 2 Puncte
- Clasa: tip nou definit in cadrul unui program (user-defined datatype) care grupeaza
impreuna mai multe informatii => similiare cu structurile
- Numele clasei => numele noului tip definit
- Membrii clasei => datele clasei, campurile clasei (structura de date a clasei) + functiile
clasei (comportamentul clasei)
- O clasa in general modeleaza (gestioneaza) o entitate.
- Fiecare entitate are in general:
o O anumita structur de date si
o Un anumit comportament.
Exemplu de aplicatie: managementul informatiilor privind situatia studentilor in ATM:
gestiunea studentilor (militari, civili), situatia scolara, situatia militara (numai pentru
studentii militari), grupe de studenti, examene, note, medii, etc., elementele logistice
(locatia in camin, gestiunea meselor, gestiunea echipamentului militar, etc.), orarul,
materiile, etc.
Putem identifica o serie de entitati: Student, Student_civil, Student_militar, Grupa,
Nota, Colectie_note, Echipament, Materie, Colectie_materii, Orar, etc.
- Variabile in cadrul programului: obiecte (instante ale clasei).
- Datele membre ale unei clase: pot fi de mai multe tipuri:
class Student
public:
int
char
float
id;
nume [256];
medie;
//...
};
- Putem avea 0, 1 sau mai multe instante ale unei clase (locale, globale, parametrii)
- Fiecare instanta are spatiul ei de memorie si setul ei propriu de date (ex: id, nume, medie)
// Referinta la studentul S1
// Referinta la studentul catre care pointeaza S2
/* Declaratia unui pointer catre un obiect Student;
Atentie: nu este alocat inca obiectul Student */
//...
S1.id = 100;
S1.medie = 9.14;
strcpy (S1.nume, "Popescu Ionel");
S1.id = 101;
strcpy (S1.nume, "Popescu Ionel");
S1.medie = 9.14;
S2->id = 102;
strcpy (S2->nume, "Vasile Mihai");
S2->medie = 8.21;
S3.medie = 9.52;
S4.medie = 9.01;
cout << S1.nume << ": " << S1.medie;
cout << S2->nume << ": " << S2->medie;
S5->id = 103;
/* crash !!! */
S5->medie = 5.25;
/* crash !!! */
strcpy (S5->nume, "Ionescu Marian"); /* crash !!! */
//...
}
- Obs: fiecare din obiectele S1, (*S2), (*S3) (daca exista undeva S3 = new Student;) vor
avea spatiul de memorie si datele proprii.
//
//
//
//
metoda
metoda
metoda
metoda
a
a
a
a
clasei
clasei
clasei
clasei
// metoda a clasei
//...
};
void Student::setId (int i) {
id = i;
}
void Student::setNume (char *n) {
strcpy (nume, n);
}
void Student::setMedie (float m) {
medie = m;
}
void Student::update (int i, char *n, float m) {
setId (i);
setNume (n);
setMedie (m);
}
void Student::print () {
cout << "\nStudent: " << id << " " << nume << " " << medie;
}
void main ()
{
Student S1;
// instanta S1 a clasei student
Student *S2 = new Student; /* declaratia unui pointer la Student si initializarea sa
cu o instanta a unui student alocat in mem heap */
Student &S3 = S1;
// referinta la studentul S1
Student &S4 = *S2;
// referinta la studentul catre care pointeaza S2 */
Student *S5;
//...
S1.setId (101);
S1.setNume ("Popescu Ionel");
S1.setMedie (9.14);
S2->setId (102);
S2->setNume ("Vasile Mihai");
S2->setMedie (8.21);
S3.setMedie (9.52);
S4.setMedie (9.01);
S1.print ();
S2->print ();
S5 = new Student;
S5->setId (103);
S5->setMedie (5.25);
S5->setNume ("Ionescu Marian");
S5->print();
}
Cerin: modelarea unor operatii cu vectori geometrici: implementarea adunarii a doi vectori.
#include <iostream>
using namespace std;
/******************************************************************************/
class Point { /* Declaratia clasei Point */
int x;
int y;
public:
void set(int a, int b) { /* functie (metoda) inline */
cout << "\nInitializare punct cu coordonate noi: " << a << ", " << b << "...";
x = a;
y = b;
}
void
void
print();
move (int off_x, int off_y);
int
int
};
/* Implementarea (definitia) clasei Point */
void Point::move (int off_x, int off_y) {
this->x = this->x + off_x;
this->y = this->y + off_y;
}
void Point::print() {
cout << "(" << x << ", " << y << ")";
}
/******************************************************************************/
class Vector { /* Declaratia clasei Vector */
char nume[32];
Point start;
Point end;
void
public:
void
void
void
Vector&
/* numele vectorului */
/* punctul de start al vectorului (originea) */
/* punctul de final al vectorului (destinatia) */
};
/* Implementarea (definitia) clasei Vector */
void Vector::set(const char *nume, int xs, int ys,
void Vector::print() {
cout << "\nDesenam vectorul '" << nume << "': ";
start.print ();
cout << " --> ";
end.print ();
}
void Vector::move (int off_xs, int off_ys, int off_xe, int off_ye) {
start.move(off_xs, off_ys);
end.move(off_xe, off_ye);
}
void Vector::align_to (Vector &V) {
this->move (0, V.start.gety() - this->start.gety(),
0, V.start.gety() - this->start.gety());
this->move (V.start.getx() - this->start.getx(), 0,
V.start.getx() - this->start.getx(), 0);
}
Vector& Vector::add (Vector &V)
{
Vector V1 = *this;
Vector V2 = V;
Vector *V3 = new Vector; // vectorul rezultat(metoda intoarce referinta catre el)
char nume[32];
sprintf (nume, "%s+%s", V1.nume, V2.nume);
V2.align_to (V1);
V3->set (nume, V1.start.getx(), V1.start.gety(),
V1.end.getx() + V2.end.getx() - V2.start.getx(),
V1.end.gety() + V2.end.gety() - V2.start.gety());
return (*V3);
}
/******************************************************************************/
void main ()
{
//...
Vector V1, V2;
V1.set ("V1", 1, 2,
V2.set ("V2", 4, 1,
// declaram vectorii
2, 4); // initializam vectorul V1
5, 5); // initializam vectorul V2
// adunam V2 + V1 => V3
// desenam noul vector "V2+V1"
// adunam V1 + V2 => V4
// desenam noul vector "V1+V2"
Cateva observatii:
- Pointerul this
- Operatorul de scop (scope access operator) ::
- Clasa Vector foloseste membrii clasei Point
- Metoda Vector::add (...) intoarce referinta catre un obiect. Atentie, este alocat
dinamic in heap. Q: cum facem putem delete ?
- Accesul la membrii non-public ai claselor se poate face numai prin metode de
acces publice. Exemplu in clasa Point::getx ( ) si Point::gety ( )
- Incapsulare !!
- ....