Sunteți pe pagina 1din 10

1

1. INTRODUCERE

1.1. Scurt istoric
Mult vreme C a fost limbajul preferat de programatori, n special de cei care dezvoltau aplicaii
pentru sistemele MS-DOS i WINDOWS. n ultima vreme ns, popularitatea limbajului C++ a
crescut datorit faptului c permite programarea orientat pe obiecte (Object-Oriented
Programming) - o metod de programare folosit n prezent pentru realizarea multor aplicaii
software.
Ideea programrii orientate pe obiecte (POO) a aprut n anii 60, fiind pus n practic prin
intermediul limbajelor SIMULA (1967) i SMALLTALK (1975). Totui, aceste limbaje au avut o
rspndire relativ redus, deoarece puini programatori formai la coala limbajelor clasice
procedurale din acea perioad (FORTRAN, COBOL, PASCAL, MODULA-2, C etc.) erau dispui
s abandoneze aceste limbaje doar de dragul de a lucra obiectual. Cu toate acestea, n anii 80, n
urma acceptrii definitive a limbajului C, un colectiv condus de Bjarne Stroustrup, un tnr
cercettor de la Bell Labs, a avut ideea scrierii unui compilator care s preia simplitatea i
flexibilitatea C-ului i mecanismele de "modelare ale limbajului SIMULA 67. Bjarne a numit acest
dialect C with Classes i, prima versiune comercial a acestuia a aprut la AT&T n 1983, cu
denumirea modificat n cea actual, C++ (sugerat de Rik Masciti, un colaborator apropit a lui B.
Stroustrup). Denumirea de C++ semnific de fapt multiplele facilitti adugate limbajului C.
Profitnd de multitudinea domeniilor de aplicaie (de la grafica interactiv la proiectarea interfeelor
utilizator i de la exploatarea reelelor de calculatoare la tehnicile de proiectare a compilatoarelor),
printre programatori n general i printre programatorii de C n particular, aproape imediat apar
partizani ai POO-ului. De ce acest succes extraordinar ? n primul rnd, din cauza faptului c
limbajul C++ nu face nimic altceva dect sa dea un nou avnt unuia dintre cele mai la mod limbaje
ale momentului (este vorba de C), iar n al doilea rnd din cauza faptului c aduce o i mai mare
economie de timp n procesul de dezvoltare-implementare-testare a aplicaiilor software. n cazul
limbajelor tradiionale procedurale (3GLs - 3
rd
Generation Languages), algoritmul materializat ntr-
o diagram de flux a datelor (DFD - Data Flow Diagram), ajunge s se adapteze arhitecturii
calculatorului. Generaia a patra de limbaje (4GLs), cum se obinuiete a se denumi categoria
acestor limbaje orientate pe obiecte, urmrete adaptarea calculatorului la obiecte.

1.2. Avantajele POO
Avantajele POO reies din definirea principalelor concepte care stau la baza POO i anume:
abstractizarea datelor (data abstraction), motenirea (inheritance) i polimorfismul (polymorphism).
Abstractizarea datelor se refer la procesul de definire a tipurilor abstracte de date, n timp ce
motenirea i polimorfismul se refer la mecanismele care permit programatorilor s beneficieze de
caracteristicile comune ale tipurilor abstracte de date (obiectele din POO).

Abstractizarea datelor
Termenul tip abstract de date se refer la un tip de date definit de programator obinut prin
ncapsularea (contopirea) datelor specifice aplicaiei cu setul de operaii (codul) care pot fi
efectuate asupra acestor date. Este numit abstract, pentru a-l diferenia de tipurile de date de baz
predefinite n C, cum ar fi int, char, float i double. Deci, definirea unui tip abstract de date
(abstract data type - ADT) implic specificarea reprezentrii interne a datelor din acel tip, precum i
a funciilor pe care alte module de program le vor utiliza pentru manipularea acelui tip abstract de
date. Ascunderea datelor, o facilitate a abstractizrii datelor, asigur posibilitatea modificrii
structurii interne a unui tip abstract de date fr a provoca funcionarea defectuoas a programelor

2
care apeleaz funciile ce opereaz asupra acelui tip abstract de date. n POO, un astfel de tip
abstract de date definit de utilizator, dar care se comport la fel ca un tip predefinit, se numete
clas (class). O clas poate fi considerat ca un model (ablon) din care pot fi create obiecte
specifice. Un obiect este o instaniere a unei clase, deci o variabil declarat ca fiind de tipul clas
respectiv.
Funciile care opereaz asupra unui obiect sunt denumite metode. Metodele definesc comportarea
unui obiect. n C++, metodele sunt denumite funcii membre (member functions) ale clasei.
Prin conceptul de ncapsulare a datelor i codului corespunztor se ating i alte obiective:
posibilitatea de localizare a erorilor (ntotdeauna cauza se afl n interiorul unei singure clase) i
modularizarea problemei de rezolvat (fiecare clas va rezolva, de regul, o singur problem).

Motenirea
Abstractizarea datelor nu acoper o caracteristic important a obiectelor i anume aceea c
obiectele din lumea real nu exist n stare izolat. Fiecare obiect este n relaie cu unul sau mai
multe obiecte. De multe ori un nou obiect poate fi descris evideniind modul n care caracteristicile
i comportarea acestuia difer fa de cele ale unei clase de obiecte deja existente. Aceast practic
de a defini noi obiecte n termeni ai unuia (unora) vechi este o parte integrant a POO i se
definete prin conceptul de motenire. Prin mecanismul motenirii, n urma definirii unei clase, cu
un minim de efort i timp, se pot preciza seturi de clase asemntoare, avnd totui o trstur
distinctiv. Motenirea impune o relaie ierarhic ntre clase, prin care o clas derivat (derived
class) motenete caracteristicile unei clase de baz (base class). Trebuie precizat c, prin
mecanismul motenirii multiple, mai multe clase derivate pot moteni o aceeai clas de baz i,
mai multe clase de baz pot fi motenite de o aceeai clas derivat.

Polimorfismul
n sens literal, polimorfism nseamn calitatea de a avea mai mult de o form. n contextul POO,
polimorfismul nseamn c ntr-o ierarhie de clase obinute prin motenire, o metod poate avea
forme diferite de la un nivel la altul (specifice respectivului nivel de ierarhie) i poate funciona
diferit n obiecte diferite. De exemplu, s considerm operaia de adunare. Pentru dou numere,
adunarea va genera suma lor. ntr-un limbaj de programare care suport POO, operaia de adunare
poate fi exprimat printr-un singur operator, semnul plus (+). Considernd acest fapt, se poate
utiliza expresia x+y pentru a indica suma lui x i y pentru mai multe tipuri diferite de numere x i y
cum ar fi: ntregi, numere n virgul mobil, numere complexe etc. Se poate chiar defini operaia +
ca nsemnnd concatenarea a dou iruri de caractere.
















3
2. C++ I PROGRAMAREA ORIENTAT PE OBIECTE

Scopul acestui capitol este de a face o scurt trecere n revist a celor mai importante caracteristici
i concepte introduse de limbajul C++. Nu se prezint detaliile sintactice ale limbajului C++, ci,
prin cteva exemple simple, se va iniia numai un prim contact al cititorului cu noile concepte.
Explicaiile furnizate aici vor fi de natur s incite la o parcurgere atent a capitolelor urmtoare n
care gradul de rafinare a informaiei va crete substanial.

2.1. Diferena dintre clas i structur
Listingul programului din Exemplul 2.1 evideniaz o serie de concepte din C++ cum ar fi: clas,
structur, constructor, obiect etc.
// Exemplul 2.1. Program P2_1.CPP Diferena dintre clas i structur
# include <iostream.h>
# include <stdio.h>
class CLS {
int a, b; // a i b sunt de tip private
public:
CLS (int z = 0) { a = b = z; } // Constructorul clasei CLS
void Imp(char *mesaj = " ") {
printf ("%s a si b = %d %d\n", mesaj, a, b);
}
};
struct STRU {
int a, b; // a i b sunt de tip public aici
STRU (int z = 0) {a = b = z;} // Constructorul structurii STRU
};
// Programul principal
void main (void)
{ CLS ob_c(1);
STRU ob_s(10);
ob_c.Imp("Dupa creare, datele obiectului ob_c devin: ");
// ob_c.a = 111; ar conduce la eroarea CLS :: a is not accessible
cout << "Datele obiectului ob_s inainte de modificare = " << ob_s.a\
<< " " << ob_s.b << endl;
ob_s.a = 100;
ob_s.b = 1;
cout << "si dupa = " << ob_s.a << " " << ob_s.b << endl;
}
Mai nti, se observ c n C++ spre deosebire de C, comentariile sunt precedate de //. Dar n C++
se accept i forma comentariului din C: /* text comentariu */.
Construcia:
class CLS {
int a, b; // a i b sunt de tip private
public:
CLS (int z = 0) { a = b = z; } / Constructorul clasei CLS
void Imp(char *mesaj = " ") {
printf ("%s a si b = %d %d\n", mesaj, a, b);
}
};

4
reprezint declararea clasei CLS. Aceast construcie pune n eviden un ablon care va servi la
crearea ulterioar a obiectelor.
Obiectul ob_c ce aparine clasei CLS este declarat n programul principal prin:
CLS ob_c(1);
Expresia ob_c(1) din aceast instruciune instruiete compilatorul ca s iniializeze ambele variabile
de tip ntreg a i b cu valoarea 1. Funcia care este automat apelat la declararea obiectului ca s
realizeze aceast iniializare este constructorul clasei CLS, denumit la fel ca i clasa, CLS. n acest
exemplu nu apare i funcia destructor al clasei. n program ntlnim i linia de comentariu
// ob_c.a = 111; ar conduce la eroarea CLS::a is not accessible
n acest stadiu s reinem doar c accesul la elementele (variabilele) a i b situate deasupra
cuvntului cheie public este ngrdit, ele fiind de tipul private. Numai prin intermediul
constructorului clasei CLS avem acces la variabilele a i b ale obiectului ob_c, nu i direct. Dac n
funcia main() am fi ntlnit linia surs urmtoare:
CLS ob_c;
ea nu ar fi fost refuzat din punct de vedere sintactic. n acest caz, a i b ar fi fost iniializate cu
valoarea asumat 0. Se vede c n interiorul constructorului CLS, z = 0. Corpul funciei CLS este
delimitat, ca oricare funcie din C, de acolade, iar aici, ca unic instruciune se ntlnete dubla
atribuire a = b = z; echivalent cu instruciunile a = z; b = z;. Deci, n C++, orice linie surs se
termin prin separatorul ; ca i n C.
Programul mai conine construcia:
struct STRU {
int a, b; // a i b sunt de tip public aici
STRU (int z = 0) {a = b = z;} // Constructorul structurii STRU
};
care este ablonul unei structuri cu numele STRU ce conine dou variabile a i b tot de tip ntreg
(ca i variabilele a i b din structura CLS) i o funcie (constructorul structurii STRU, denumit tot
STRU). Obiectul ob_s creat n linia
STRU ob_s(10);
va iniializa variabilele a i b cu valoarea 10. i aici, n lipsa unei valori explicite, a i b vor fi
iniializate cu valoarea asumat n constructor, 0. De data aceasta variabilele a i b din structura
STRU fiind de tip public sunt accesibile din orice instruciune din funcia main(), fr a apela la
serviciile constructorului. Deci, putem scrie:
ob_s.a = 100;
i variabila a din obiectul ob_s devine egal cu 100, n loc de 10.
Se observ de asemenea c, att constructorul clasei CLS ct i constructorul structurii STRU sunt
definii n interiorul acestora, sau altfel spus sunt definii n modul inline.
n sfrit, acest program ne arat i modalitatea afirii datelor; este vorba de liniile n care apare
cuvntul cheie cout, echivalentul funciei printf() din limbajul C, dar mai comod dect aceasta.
Funcia printf() este acceptat i n C++ i pstreaz ncorsetrile din C. De exemplu n C, pentru
afiarea valorii variabilei ntregi j, se recurge la secvena:
# include <stdio.h> // Prototipul funciei printf() este definit n fiierul antet stdio.h
...
int j = 10;
printf (j = %d\n, j);
Funcia printf() are dou argumente: j = %d\n i j. Primul argument conine un ir de caractere i
un caracter de conversie. Acesta este precedat de caracterul %. Cnd compilatorul ntlnete %d
acesta este atenionat c va fi afiat un ntreg n format zecimal, n cazul nostru al doilea argument
al funciei printf(), adic ntregul j. Ieirea se efectueaz la fiierul logic stdout (de regul atribuit
ecranului videoterminalului).

5
Dac j ar fi fost de tipul double (virgul mobil, dubl precizie), formatul trebuia modificat din %d
n %f (sau %g). Deci, am fi avut:
...
double j = 10;
printf (j = %f\n, j);
n acest caz, j s-ar fi transformat din reprezentarea intern n virgul mobil, ntr-un format extern
zecimal propriu acestei reprezentri (de exemplu, mmmmmm.nnnnnn).
n contextul limbajului C++, cout nlocuiete stdout. Acesta este alctuit din literalul "Datele
obiectului ob_s inainte de modificare = ", urmat de variabila ob_s.a, apoi de un al doilea literal " "
(adic un ir de spaii), i n sfrit de variabila ob_s.b. Dac a i b ar fi fost de tip double, nu mai
trebuia schimbat nimic n linia surs n care apare obiectul cout, membru al clasei ostream; aceasta
deoarece pentru fiecare tip de informaie, C++ pune la dispoziie n contextul obiectului cout o
metod (funcie), care analizeaz i nelege mesajul (inclusiv tipurile variabilelor care trebuie
afiate) i realizeaz conversiile adecvate. Elementele clasei de ieire ostream se afl n fiierul
antet iostream.h, inclus n exemplul de fa prin linia:
# include <iostream.h>.

Funcia membr a clasei
Pentru a afia variabilele a i b ale clasei CLS, aceasta conine funcia Imp definit prin:
void Imp(char *mesaj = " ") { printf ("%s a si b = %d %d\n", mesaj, a, b); }
i numit funcie de tip membru (member) al clasei. Se observ c aceasta este definit n corpul
clasei CLS, deci inline, n poriunea public a acestei clase, accesibil din orice funcie inclusiv din
funcia main(). Cuvntul cheie void din faa funciei Imp arat c aceasta nu ntoarce nici un
rezultat. De altfel, din corpul funciei Imp lipsete instruciunea return. Prezena sa ar fi ilegal,
dac s-a stabilit c funcia Imp nu ntoarce nici un rezultat. Variabila mesaj este un pointer (notaie
*mesaj) la un ir de caractere. Formatul listrii unui ir de caractere este %s. irul asumat, n lipsa
unui text atribuit lui mesaj, este un ir de lungime nul (ir vid). Variabilele a i b fiind de tipul
ntreg, fiecare vor fi asociate unui format %d. Notaia \n este caracterul de tip spaiu alb (white
space) numit avans la linie nou (line feed, cod 0x0a n hexazecimal sau 10 n zecimal).
Funciile de tip membru au privilegiul de a avea acces direct la variabilele clasei, inclusiv la cele de
tipul private. Nu a mai fost nevoie de construcii de genul ob_c.a sau ob_c.b, ci referirea s-a fcut
direct la a sau b. Pentru aflarea valorilor variabilelor a i b ale obiectului ob_c, n funcia main() a
fost adugat linia urmtoare:
ob_c.Imp("Dupa creare, datele obiectului ob_c devin:");
plasat undeva dup linia:
CLS ob_c(1);
O alt variant a funciei Imp() este cea n care nu se mai recurge la serviciile funciei printf(), ci la
cout:
void Imp(char *mesaj = " ") { cout << mesaj << a << << b << endl; }
Cuvntul endl este echivalentul lui \n din C.
Funciile inline au avantajul c la apelarea lor nu se mai parcurg secvenele (de regul lungi) de
salvare n stiv a parametrilor de intrare, execuia crescnd n rapiditate.

2.2. Redefinirea funciilor i operatorilor
Pentru a prezenta alte caracteristici ale limbajului C++, considerm listingul programului din
Exemplul 2.2.
// Exemplul 2.2. Program P2_2.CPP
// O clasa cu constructor, destructor, o functie membru redefinita
// si o alta functie care redefineste operatorul || pentru concatenarea unor siruri

6
# include <string.h>
# include <stdio.h>
class SIR {
char *text;
public:
SIR (char *sir); // Constructorul clasei
~SIR () { delete text;} // Destructorul clasei
int compar (SIR &s1, SIR &s2);
int compar (SIR &s1, SIR &s2, unsigned int ncar);
void operator || (SIR &s) {strcat (text, s.text);}
void Imp (char *mesaj = " ") {
printf ("%s = %s\n", mesaj, text);
}
};
SIR::SIR (char *sir) // Definirea constructorului
{
text = new char[strlen(sir)];
strcpy (text, sir);
}
int SIR::compar (SIR &s1, SIR &s2)
{
return strcmp (s1.text, s2.text);
}
int SIR::compar (SIR &s1, SIR &s2, unsigned ncar)
{
return strncmp (s1.text, s2.text, ncar);
}
// Programul principal
void main (void)
{ SIR sir1 ("abcd"), sir2 ("abcdef"); // Se creeaza 2 obiecte de tip sir
sir1.Imp ("Primul sir este: ");
sir2.Imp ("Al doilea sir este: ");
int rez1, rez2;
rez1 = sir1.compar (sir1, sir2);
printf ("Rezultatul primei comparatii este %d\n", rez1);
rez2 = sir1.compar (sir1, sir2, 4);
printf ("Rezultatul celei de-a doua comparatii este %d\n", rez2);
sir1 || sir2;
sir1.Imp ("Sir1 dupa concatenare este: ");
}
Programul conine clasa SIR n care singura dat de tip private este pointerul la un ir de caractere
*text. Constructorul SIR i funcia compar() sunt numai declarate n cadrul clasei, pe cnd
destructorul ~SIR i funcia denumit operator||() sunt definite n mod inline. Faptul c denumirea
compar este ntlnit de dou ori nu este o eroare. Funcia compar() este redefinit. Ea are dou
abloane (prototipuri). Primul ablon este utilizat cnd se compar dou iruri de lungimi diferite
sau nu, iar al doilea cnd se compar numai primele ncar caractere ale acestora. Notaiile SIR &s1,
SIR &s2 reprezint referinele celor dou iruri ce trebuie comparate.
Funcia SIR este definit n afara clasei prin:

7
SIR::SIR (char *sir) // Definirea constructorului
{
text = new char[strlen(sir)];
strcpy (text, sir);
}
n care apare notaia :: prin care se precizeaz apartenena unei funcii la o anumit clas.
Instruciunea
text = new char[strlen(sir)];
arat c, ncepnd de la adresa text, operatorul new va aloca un numr de caractere egal cu
lungimea efectiv a sirului sir. Lungimea irului este returnat de funcia strlen() (string length). n
limbajul C pentru alocarea dinamic a unui spaiu de memorie se folosete funcia malloc() care
cere specificarea numrului de octei. Deci, n C scriem:
text = malloc (strlen (sir));
fapt acceptat i n C++. Instruciunea strcpy(text, sir); realizeaz copierea irului sir n spaiul alocat
la adresa text. Prototipurile funciilor strlen() i strcpy() (string copy) sunt declarate n fiierul antet
string.h. Operatorul delete din definiia destructorului ~SIR este opusul lui new i are ca efect
eliberarea zonei de memorie ocupat de obiect. n C, opusul funciei malloc() este funcia free().
Deci, echivalena din C a liniei delete sir; este linia free(sir).
Funcia compar() ntoarce un rezultat de tip ntreg. Celor dou prototipuri declarate n clasa SIR le
corespund dou definiii. Primul prototip trateaz cazul comparrii a dou iruri de lungime
oarecare:
int SIR :: compar (SIR &s1, SIR &s2)
{ // Se compar d.p.d.v. lexicografic dou iruri de caractere
return strcmp (s1.text, s2.text);
}
Funcia strcmp() cu prototip n fiierul antet string.h, ntoarce rezultatul comparaiei a dou iruri
de caractere. Pentru compararea primelor ncar caractere din dou iruri, definiia este urmtoarea:
int SIR :: compar (SIR &s1, SIR &s2, unsigned ncar)
{ // Comparaia primelor ncar caractere din dou iruri
return strncmp (s1.text, s2.text, ncar);
}
Valoarea rezultatului comparaiei cu funciile strcmp() i strncmp() se obine prin scderea
nedistructiv a caracterelor celor dou iruri aflate pe aceeai poziie relativ. Dac:
s1 < s2, rezultatul < 0
s1 == s2, rezultatul = 0
s1 > s2, rezultatul > 0
Al treilea membru al clasei SIR redefinete operatorul || (operatorul logic SAU), adic asociaz
operatorului || un sens nou. Prin construcia void operator || (SIR &s) se anun compilatorul C++
c operatorului || i-a fost temporar asociat sensul descris n corpul funciei: { strcat (text, s.text); }.
Instruciunea dintre acolade are ca efect concatenarea a dou iruri. Lista de parametri text, s.text
ascunde dou referine la irurile obiectului curent (text), respectiv al obiectului s (s.text). Se
alipete deci irul punctat de ctre s.text la irul punctat de pointerul text. Funcia strcat() al crui
prototip se afl n fiierul string.h nu ntoarce nici un rezultat.
n programul principal se creeaz dou obiecte sir1 i sir2 cu structura sir1 = a b c d \0, respectiv
sir2 = a b c d e f \0. n linia rez1 = sir1.compar (sir1, sir2); se realizeaz compararea celor dou
iruri de lungime diferit. Se va utiliza prima form a funciei compar(). irurile nefiind identice,
funcia va ntoarce n variabila rez1 o valoare negativ. Se remarc construcia:
nume_obiect.nume_metoda (lista_de_argumente).

8
Linia rez2 = sir1.compar (sir1, sir2, 4); conduce la o comparaie conform celei de a doua metode,
care se bazeaz pe funcia strncmp. Cum, primele 4 poziii ale celor dou iruri coincid, n variabila
rez2 se va gsi valoarea 0. n urma concatenrii, sir1 se va prelungi, n el regsind acum valoarea a
b c d a b c d e f \0, fapt atestat prin executarea liniei sir1.Imp ("Sir1 dupa concatenare este: "). i
aici se observ prezena construciei nume_obiect.nume_metoda (lista_de_argumente) n care
operatorul punct (.) unete obiectul cu funcia apartenent la clasa care la creat.

2.3. Despre motenire, clase derivate i reutilizarea codului
Considerm un program care conine clasa RAND_UNIF, prin care se genereaz numere aleatoare
cu o distribuie uniform.
// Exemplul 2.3. Program P2_3.CPP
// Generarea unor numere aleatoare cu distributie uniforma prin metoda liniar congruentiala
# include <limits.h>
class RAND_UNIF {
long x;
void gen_nr () { x = x*1103515245 + 12345; }
public:
RAND_UNIF (long n = 0) {x = n;} // Constructorul clasei
void seed (long n);
unsigned int ui_unif () {
gen_nr ();
return x & LONG_MAX;
}
double d_unif () {
gen_nr ();
return (x & LONG_MAX) / (double) LONG_MAX;
}
};
// Generarea a 10 numere aleatoare intregi si in virgula mobila, care sunt uniform distribuite
// in gamele [0...LONG_MAX] si [0...1]
# include <stdio.h>
void main (void)
{
RAND_UNIF aleator; // Se creeaza obiectul aleator
unsigned int nai;
double nad;
for (int i = 0; i < 10; i++) {
nai = aleator.ui_unif ();
nad = aleator.d_unif ();
printf ("i - numerele aleatoare uniform distribuite = %d %u %f\n", i, nai, nad);
}
}
n clasa RAND_UNIF, n seciunea private, pe lng variabila x de tip long este ncapsulat i
funcia gen_nr() de tip inline. Funcia membru ui_unif() este definit n modul inline. Ea apeleaz
la serviciile funciei gen_nr(), cu care genereaz numere ntregi fr semn cu relaia: x =
x*1103515245 + 12345. Deoarece prima dat seed() este 0, x va fi egal cu 12345. Valorii x i se
aplic o masc binar LONG_MAX (o constant definit n fiierul antet limits.h, a crei valoare
depinde de tipul calculatorului; de exemplu, n cazul unui calculator care permite un ntreg lung pe
32 bii, LONG_MAX = 2
31
-1). Datorit acestei mti se asigur tiere bitului de semn.

9
n cadrul funciei main() se creeaz mai nti obiectul cu numele aleator, dup care, utiliznd bucla
for se genereaz primele 10 numere aleatoare.

S presupunem acum c dorim s generm numere aleatoare uniform distribuite, ns ntre dou
limite stabilite de noi. Mai mult, nu vrem s modificm clasa RAND_UNIF, ci s utilizm att
structura de date, ct i codul anterior. De asemenea, se dorete realizarea unui generator de numere
cu o distribuie exponenial n jurul unei valori medii.
Pentru aceasta, vom alctui dou clase derivate din clasa de baz RAND_UNIF. Listingul n care
apar aceste clase denumite R_UNIF_LIM i R_EXP_LIM este prezentat n Exemplul 2.4.
// Exemplul 2.4. Program P2_4.CPP
// Declararea si definirea clasei de baza pentru generarea unor numere aleatoare cu distributie
// uniforma prin metoda liniar congruentiala
# include <limits.h>
# include <math.h>
class RAND_UNIF {
long x;
void gen_nr () { x = x*1103515245 + 12345; }
public:
RAND_UNIF (long n = 0) {x = n;} // Constructorul clasei
void seed (long n);
unsigned int ui_unif () {
gen_nr ();
return x & LONG_MAX;
}
double d_unif () {
gen_nr ();
return (x & LONG_MAX) / (double) LONG_MAX;
}
};
// Declararea si definirea claselor derivate
struct R_UNIF_LIM : public RAND_UNIF {
int inf, sup;
R_UNIF_LIM (int i, int s) {inf = i; sup = s;}
unsigned int ui_unif ();
};
struct R_EXP_LIM : public RAND_UNIF {
int media;
R_EXP_LIM (int m) { media = m; }
unsigned int ui_unif ();
};
unsigned int R_UNIF_LIM :: ui_unif () // Se redefineste ui_unif()
{
return (unsigned int) ((RAND_UNIF::ui_unif () % (sup-inf)) + inf);
}
unsigned int R_EXP_LIM :: ui_unif () // Se redefineste ui_unif()
{
return (unsigned int) (-media * log(1.0-RAND_UNIF::d_unif ()) + 0.5);
}

10
// Generarea a 100 numere aleatoare uniform distribuite in gama [INF...SUP]
// si exponential distribuite in jurul valorii MEDIA
# define INF 10
# define SUP 100
# define MEDIA 500
# include <stdio.h>
void main (void)
{
R_UNIF_LIM n(INF,SUP); // Se creeaza obiectul n
R_EXP_LIM m( MEDIA ); // Se creeaza obiectul m
unsigned int nai;
unsigned int naexp;
for (int i = 0; i < 100; i++) {
nai = n.ui_unif ();
naexp = m.ui_unif ();
printf ("i - numerele aleatoare uniform distribuite si exponential distribuite\
= %3d %3u %4u \n", i, nai, naexp );
}
}
n acest exemplu se evideniaz modul declarrii unei clase derivate, astfel:
struct R_UNIF_LIM : public RAND_UNIF{

Tipul clasei derivate este struct, adic structur. Variabilele inf i sup ale structurii sunt publice,
deci direct accesibile din program. Se observ c funcia ui_unif() va fi reutilizat de ctre cele
dou clase derivate, conform definiiilor precizate mai sus. Cele dou redefiniri ale funciei
ui_unif() permit determinarea distribuiilor menionate mai sus. De fapt, pentru determinarea unor
numere uniform distribuite n gama [INF...SUP] i exponenial distribuite n jurul valorii MEDIA,
am motenit metoda de determinare a numerelor uniform distribuite ntre limitele 0, ...,
LONG_MAX i cu ea am creat dou metode noi pentru determinarea distribuiilor precizate.

2.4. Caracteristici ale limbajului C++ - limbaj orientat pe obiecte
1. Clasa este o structur de date abstract, un ablon, care, pe lng date, conine i funcii, fapt
neobinuit n limbajul C;
2. Obiectul este creat de ctre productorul (constructorul) clasei conform ablonului acesteia;
3. Mecanismul de ascundere a datelor const n tehnica de plasare a valorilor n variabilele de tip
private ale obiectului;
4. Motenirea este proprietatea unui obiect de a prelua anumite proprieti ale obiectelor
apartenente unei clase de baz (ierarhic superioare).
5. Obiectele comunic ntre ele prin mesaje. Funciile membre ale clasei (metodele) interpreteaz
mesajele (valorile argumentelor) i asigur comportarea corespunztoare a obiectelor.
Polimorfismul, o noiune care este corelat cu comportamentul diferit al unei metode n raport
cu tipul obiectului va fi explicat n cursurile urmtoare.
6. Constructorul i destructorul sunt funcii speciale ale unei clase. Constructorul este automat
apelat la crearea obiectelor, iar destructorul elibereaz resursele de memorie ocupate de acel
obiect la momentul ncheierii existenei acelui obiect.
struct R_UNIF_LIM : public RAND_UNIF {

Tipul i numele clasei derivate Numele clasei de baz

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