8Clase
8.1Definirea unei clase
Clasa este o reprezentare a unui tip de date abstracte. Clasa defineşte variabile (atribute) şi funcţii (metode) care implementează structura de date şi operaţiile tipului abstract şi asigură detaliile de implementare pentru structura de date şi pentru operaţii.
Un obiect este o instanţa a unei clase (a unui tip abstract). El este unic identificat prin nume şi defineşte o stare reprezentată de valorile variabilelor (atributelor) la un moment dat. Comportarea unui obiect este definită de funcţiile (metodele) definite de clasă ce se pot aplica asupra lui. Definirea unei clase are forma
class NumeClasa
{
specificator_acces:
date şi functii membre
specificator_acces:
date şi functii membre
………………………..
specificator_acces:
date şi functii membre
};
Clasele sunt definite utilizând cuvântul cheie class. Specificatorii de acces sunt public, protected şi private.
-
membri publici ai clasei pot fi utilizaţi de orice funcţie din program,
-
membri privaţi ai clasei pot fi utilizaţi doar de funcţiile membre ale clasei,
-
membrii protejaţi ai clasei pot fi utilizaţi de funcţiile membre ale clasei şi de cele ale claselor derivate.
Implicit toţi membri clasei sunt privaţi.
În limbajul C++ avem posibilitatea de a grupa anumite nume în spaţii de nume. Prin definiţie, datele şi funcţiile unei clase constituie un spaţiu de nume ce are numele clasei. Operatorul de rezoluţie "::" arată că un nume de variabilă sau de funcţie aparţine unui spaţiu de nume. Operatorul de rezoluţie "::" se utilizează pentru a defini o funcţie membru a clasei în afara clasei. Definirea funcţiilor membre ale unei clase se poate face, fie în interiorul clasei, fie în afara clasei, dacă în interiorul clasei s-au declarat ca prototipuri.
Obiectele unei clase sunt create şi iniţializate de funcţii membre ale clasei special definite pentru acest scop numite constructori. O funcţie constructor are numele clasei şi nu are niciun tip (nu returnează nicio valoare). Ea are prototipul
NumeClasa(lista de parametri);
Un constructorul al unei clase este automat apelat de sistem la crearea unui obiect. O clasă poate avea mai mulţi constructori. Clasele pot avea şi următorii constructori:
NumeClasa(); // constructor implicit
NumeClasa(const NumeClasa &); // constructor copiere
Constructorul copiere crează o copie a unui obiect. El este apelat când creăm un obiect a de tipul X cu aceleaşi atribute ca b cu instrucţiunea
X a(b);
sau când un obiect este pasat ca argument prin valoare unei funcţii (este copiat în stivă).
Constructorul implicit este apelat când creăm un obiect a de tipul X cu instrucţiunea
X a;
sau când definim un tablou de obiecte.
Dacă în program nu se definesc explicit alţi constructori, compilatorul generează automat un constructor implicit.
Deoarece constructorii au, în general, rolul de a iniţializa variabilele obiectului, limbajul are o sintaxă specială de iniţializare numită listă de iniţializatori de forma
v1(p1), v2(p2), …
unde v1, v2, … sunt variabilele obiectului ce vor fi iniţializate, iar p1, p2, … sunt valorile ce vor fi atribuite variabilelor (parametrii constructorului).
Obiectele sunt distruse când nu mai sunt necesare de cǎtre funcţii membre ale clasei numite destructori. Funcţia destructor are prototipul
~NumeClasă();
Destructorul unei clase este apelat automat de sistem la distrugerea unui obiect. Destructorul nu are tip şi nici parametri.
Apelul unei funcţii a clasei de către un obiect se face cu o instrucţiune de forma
NumeObiect.numeFuncţie(lista de parametri)
Utilizarea unui câmp al unui obiect se face cu expresia
NumeObiect.numeCâmp
8.2Probleme rezolvate
Problema 1. Să se construiască o clasă Line ce descrie funcţia liniară
f(x) = m x + n
Vom defini funcţii ale clasei ce vor calcula valoarea funcţiei într-un punct şi integrala definită. Definiţia clasei este
/*
clasa Line descrie functia f(x) = m * x + n
*/
class Line
{
private:
double m, n;
public:
double value(double);
double intgrl(double, double);
void print();
Line(double, double);
};
Funcţia print() afişază pe ecran parametrii m şi n ai funcţiei, funcţia value() calculează valoarea funcţiei într-un punct, iar funcţia intgrl calculează integrala funcţiei între două valori date.
a) Prima variantă, funcţiile membre sunt definite în interiorul clasei. Pentru constructor vom folosi lista de iniţializatori.
#include
using namespace std;
/*
clasa Line descrie functia f(x) = m * x + n
*/
class Line
{
private:
double m, n;
public:
double value(double x)
{return m * x + n;}
double intgrl(double a, double b)
{return m * (b * b - a * a) / 2 + n * (b - a);}
void print()
{cout << "functia f(x) = m * x + n, "
<< " m = " << m << " n = " << n << endl;}
Line(double a, double b) : m(a), n(b) {}
};
int main(){
// creaza un obiect de tipul Line
Line a(1.7, 1.5);
a.print();
cout << "f(0.5) = " << a.value(0.5) << endl;
cout << "intgrala f(x) de la 0 la 2 = " << a.intgrl(0, 2) << endl;
return 0;
}
Rezultatele rulării programului sunt cele de mai jos.
b) A doua variantă, funcţiile membre sunt definite în afara clasei. În acest caz utilizăm operatorul de rezoluţie "::" pentru a arăta că funcţiile definite în afara clasei sunt membre ale clasei.
# include
using namespace std;
/*
clasa Line descrie functia f(x) = m * x + n
*/
class Line
{
private:
double m, n;
public:
double value(double);
double intgrl(double, double);
void print();
Line(double, double);
};
double Line::value(double x)
{
return m * x + n;
}
double Line::intgrl(double a, double b)
{
return m * (b * b - a * a) / 2 + n * (b - a);
}
void Line::print()
{
cout << "functia f(x) = m * x + n, "
<< " m = " << m << " n = " << n << endl;
}
Line::Line(double a, double b)
{
m = a;
n = b;
}
int main(){
// creaza un obiect de tipul Line
Line a(-1.7, 1.5);
a.print();
cout << "f(0.5) = " << a.value(0.5) << endl;
cout << "intgrala f(x) de la 0 la 1.5 = " << a.intgrl(0, 1.5) << endl;
return 0;
}
În unele cazuri avem nevoie să utilizăm şi să modificăm datele unui obiect în timpul execuţiei programului. Dacă datele sunt declarate private, nu putem face acest lucru direct. O soluţie este următoarea. Pentru ca o funcţie externă să aibǎ acces la membri privaţi ai clasei, ea trebuie declarată în definiţia clasei ca funcţie prietenă, friend. Diagrama sintactică a definiţiei unei funcţii prietene este
friend tip numeFuncţie ( parametri);
Vom aplica această metodă în cazul definirii unei funcţii care să efectueze suma a două funcţii liniare.
Problema 2. Vom defini o funcţie globală care să adune două funcţii liniare. Considerăm două funcţii liniare, şi . Suma lor va fi funcţia . Mai jos vom prezenta doar definiţiile funcţiei sum şi constructorului fără parametri, definiţiile celorlalte funcţii sunt neschimbate.
/*
clasa Line descrie functia f(x) = m * x + n
*/
class Line
{
private:
double m, n;
public:
double value(double);
double intgrl(double, double);
void print();
Line(double, double);
Line();
friend Line sum(const Line x, const Line y);
};
// definitia constructorului implicit
Line :: Line ()
{
m = 0;
n = 0;
}
// definirea functiei prietene sum
Line sum(const Line x, const Line y)
{
Line temp(x.m + y.m, x.n + y.n);
return temp;
}
int main()
{
Line a(1.5, 2.3);
a.print();
Line b(2.2, -1.5);
b.print();
Line c;
c = sum(a, b);
c.print();
return 0;
}
Rezultatele rulării programului sunt cele de mai jos.
Mediile de programare pot afişa structura claselor ca mai jos.
Dostları ilə paylaş: |