Sunteți pe pagina 1din 218
Success with C++ Kris Jarnea Copyright © 1994 Jamea Press Succes cu C++ Kris Jamsa ‘Traducere: Ion Fatu Copyright © 1997 - Bditura ALL EDUCATIONAL S.A. ISBN 973-9229-56.0 ‘Toate dropturile rezervate Buiturii ALT, EDUCATIONAL $.A. [Nici o parte din acest volum nu poate f copiata {ara permisiunea serisi a Béiturii ALL EDUCATIONAL S.A. Drepturile de distribute in strainitate apartin in exclusivitate editur Copyright © 1997 by ALL EDUCATIONAL 8.4. All rights reserved. "The distribution ofthis book outside Romania, without ‘the written permission of ALL EDUCATIONAL S.A. is strictly prohibited Edura ALL EDUCATIONAL S.A, 34, Timigoara nr. 58, sector 6, cod 76548 ‘@ 912.11.46, 912.43.2), 311.07.44 Fax: 81.05.65 Departament eifuzare: 9 912,18.21, 91.15.47 Rodactor: poof Usorice Fate i Mihai Ministers Tehnoredactere computerzaté: Roxana Cornelia Nistor PRINTED IN ROMAN SUCCES CU C++ KRIS JAMSA Traducere: Ion Fatu HUIWLU sei Incolectia SO WaTE a editurii ALL EDUCATIONAL ‘Au apinst: 1. Microsoft Access pentru Windows 95, Ghid de referinta - James B. Powel © Sybex 2, Ghidul secret al caleulatorului - Russ Walter © Sybex 3, Word pentru Windows 95 - usor si rapid - Christian Crumlish © Sybex 4, Bxcel pentru Windows 95 - ugor sirapid- Gerald B. Jones © Sybex 5. Microsoft Excel pentru Windows 95. Ghid de referinta - Douglas E. Hergert © Sybex 6, Primii pagi in Internet - Christian Crumlish ore Vor aptrea: WED AUTOM, | aoe $2883) 1. Biblioteca programatorului ActiveX - Suleiman Lalani, Ramesh Chandak ‘© Jamsa Press 2. Ghidul programatorului in Web - Kris Jamsa, Suleiman Lalani, Steve Weakley ‘© Jamsa Press 3. Biblioteca programatorului Java - Suleiman Lalani, Kris Jamsa Odamsa Press ee 4, Programarea in Internet - Kris Jamsa, Ken Cope (© Jamsa Press CUPRINS ‘Sectiunea 1 - Acomodarea Capitotul 4 ‘Acomodarea cu tastatura gi ecranul SSA Inielegem strear-urile /O ‘Sa Injelegem cin $i cout Redirectarea stream-urilor VO Folosirea altor stream-uri vO Rediijarea iesii programelor Sa Injelegem stream-urie VO Sa injelegom stean-uile de inrare giiegre Caractere speciale LCucrut cu manipulator Stablirea bazei de conversie Control &timii zonei de aliniere oe Stablirea caracterului de umplere sn : 4 BeDDODODARO™ > Controlul aig valorlor In virgula mobila 2, Golirea butfer-ulul 8 Ignorarea spatilor aibe ce preced datele de intrare B Controlulindicatorilor streamului WO. a 14 ‘Afigarea valoriior hexazecimale cu majuscule tS Alinierea rezultatelor la stanga sau la dreapta 16 - Gontrolulafigri cu punt fix si cu exponent. 16 Fortarea afigari punctului zecimal Mnninnnnanncne Nt Fortarea afigarii semnului unei valori : 18 Refacerea indicatorlor stream-urilor VO ann 18 Folosirea indicatorior WO... : 19 Faciliat oferite de functile membru ale stream-ului de intrare 19 Determinarea numarului de caractere extrase snr Cities unel ini de la tastatura sau de la stdin E20) Folosirea funetilor membru ale stream-ului cin ems] Realizarea operatilor de intrare caracter cu catacter 22 ‘Anticiparea urmatorului caracter [a intrare a 23 Readucerea unui caracter In buffer-ul de intrare one Detectarea sfarsitulul de figier : cS Ignorarea caracterelor din stream-ul de intrare - 25 Gitrea 51 salvarea difertelor valor ale parametrior VO... 26 : e ete s ‘$8 infelegem parametri stream-ulul de 1egif@ oe ennnnnene BT . . Faciitat oferte de functile membru ale stream-ului de iegire 2 Folosirea functilor membru ale stream-ulul cout... 28 ‘Testerea reusitei operatilor 1! 28 83 intelegem starea unui stream iO... 30 Vil Succes cu C++ Intrar-iesiri cu gi fra buffer Golirea unui buffer de lesire i Folosirea functilor membru pentru controlul indicatonlor de stream VO Rezumat Capitotul 2 ‘Acomodarea cu clase gi obiecte Primul contact cu programarea orientaté pe obiecte Sa infelegem promovarea orientatd pe obiecte Sa simpliicam defintile unel clase ‘38 intelegem mostenirea ..... Ingineria programelor $i folosirea obiectelor ‘Sd infelegem obiectele si clasele Diferenta intre clase si cbiecte Analiza unui exemplu complet wn. Cand se folosesc clasele gi cand structurile ‘Accesul la membriunei clase . Folosirea functor inline Definirea functilor membru in afara clasei Rezolvarea confictelor de nume Intre membri si parametti Rezolvarea conflictelor de nume : * Sa infelegem membri de tip private ai unei clase ‘Sa infelegem membri de tip private ai unei clase 'S8 infelegem camufiajul informatie ‘Sa infelegem constructoni i destructori unei ciase ‘Sa Injelegem functile constructor 8 intelegem functile destructor Sa infelegem functile destructor Folosirea functilor constructor multiple Folosirea argumentelor prestabilte la functile constructor Un alt mod de a intiaiza membrii unei clase : Atribuirea valoril unui obiect alt object Obiecte gi functi Folosirea obiectelor si a functilor ‘Sa Infelegem membriiunei clase Folosirea unui tablou de clase Rezumat Capitotul 3 ‘Acomodarea cu fisiorel a Intelegem operatile UO cu fisiere + Deschiderea unui figier pentru iesiré Deschiderea unui figier pentru iesire Folosirea functiei constructor pentru deschiderea unui figier Folosirea manipulatotilor gia functilor membru de iesire .. Vill 30 31 31 33 Cuprins Realizarea operator de scriere formatata a fisierelor 7 Sofierea formatata a figierelor ee 78 Controlul modului de deschidere a fgierelor de lesire ..... 78 Caractere speciale gi fsiere VO 73 Ati specificatori al modului de deschidere a fsierelor 79 Controlul operajwor pe fisiere 80 Deschiderea fisierelor pentru operatii de intrare at izarea operatilor de intrare pe fisiee ... semen OF Deschiderea unui fisier pentru intrare see 83 Testarea reugitel unei operafi YO 84 Realizarea operatilor pe figiere binare : eta Realizarea operatilor pe fisiere binare een BQ Aeentie la operatile de insertie/extractie cu fsiere binare 89 Desch derea fisierelor pentru operat de citre gi SCti@7@ .snronnnnenn nn 92 Figiere cu acces aleator 92 Recaptularea modurilor de deschidere a unui gier 94 3 Intelegem figierele cu acces aleator 97 Realizarea iesii la imprimanté snr snes ST Rezurat nn 8B Capitolul 4 ‘Acomodarea cu mostenirea claselor Conceptul de mostenire o ‘Analiza unui exemplu simplu . SA intelegem mostenirea Clason y...nsnnnssnennnnneen. 108 Folosirza functilor constructor la mostenirea claselor : 107 Analiza unl ex2MplW on . 110 'S8 Infelegem cuvantul-chete public’... 112 Analiza altul exemplu see errs Un ultim exemplu de mostenire pe un singur nivel 116 Prototipur,revizil finalizar sminnnoannanannnnnanan AY Sa infelegem mostenirea muttipla 122 Sa Infelegem mostenirea muttipla .. 125 'S3 Intolagom mogtenirea pe mai multe nivele ree 125] Sa Intelegem membril de tip protected ai unei clase semen 1B ‘Sa Infelegem membrii protejai ai unei clase 131 Rezumat 7 . 131 Capitotul 5 ‘Acomodarea cu suprapunerea functillor gi operatoriior 133, ‘Sa Inteegem suprapunerea functillor . 134 'S8 Intelegem suprapunerea functilor.. sonnei 135 >) pentru a atribui variable firstname iterele introduse Hinclude > Firstar cout << “Hello, * <« first_nase } Programul foloseste operatorul de iesire pentru a afiga solicitarea de introduce- re a numelui ullizatorului, dupa care, folosind operatorul de intrare, atribuie va- rlabllelfirst_narne lterele tastate. Apo, foloseste Inca o data operatorul de iesire pentru a afiga mesajul ,Hello*, urmat de numele introdus: cout << “Hello, * << first nane: Cand tiparitiinformati folosind operatorii de extractie mulipla in acest «nod, (C++ afigeazd inforshatia aga cum apare in instructiune, dela stanga’Spré dreap- ta. Rulat! programul anterior si introduce prenumele, urmat apoi de numele dvs. Veti vedea c& programul afigeaz numai prenumele, indiferent de informa. 4: Tastatura si ecranul Hinclude vyotd maixvoid) char frst_nanef64]: char Vast fiame( 64]: cout << “Type your first and last nanes: Cin > first_nane >> Tast_nane: cout << “Hello, * > first_rane >> Tast nane: Cand folositi doi sau mai multi operatori de extragere in aceeasi instructiune, C++ alribule variabilelor valorile de la intrare, incepind de la stanga spre sreapta, Observati, de asemenea, folositea ghilimelelor in mesajul de iesire, pentru a separa prenumele de nume. Daca indep&rtaii ghilimelele, numele va fi seri, fa pauza, in continuarea prenumelul cout << “Hello, * << Firstname SUCCESS > OUTPUT.OAT Urmatorul program, LINE_NBR.CPP, afigeaza un intra redirjate. war In faga flecdrel Yinil a include LINE NBR < SUCDESS.CRP 2 3 void masn(votd) 4 ( 50 . ne pets 5 cout CUTPUT.OAT «Enter FOLOSIREA ALTOR STREAM-URE I/O Majoritatea programelor C++ pe care le vet) intalni folosese stream-urile de YO cin $i cont. Asa cum se va vedea, fisieru IOSTREAMLH defineste gi stream-urite VO cerr gi clog. Tabela 1.1. deserle pe scurt diferite stream VO" Stream _ Sop. Exemplu cin rare tata (stn) cin >> name cout iepreecran stdout) cout <<“iello, woe etree spent ero standard (der) com <<"Broate ced dog__epre buferiata pe spony era standard (stden)_clog <<"Meso)eroare Tabla 1.1, Rezunat al stream-arilor HO dis C++ "REDIRUAREA TESIRI PROGRAMELOR Cand se ruleazi un program, C++ asdctaza streamate WO fn si cout ca ckpoztivele standard de inirare, respectiv iesie. In rod prestabiit,sistemul de operare asimileazs fispoctivul standard de inrare cu tastalura, iar dispoztvul Standard de iesite cu ecranul monitoruti, Daca se apeleaz tin program C++ folosind operator de redinare VO fn linia {ge comands, se ponte rein nara gi exiea program Cu ate cuvinte 86 ‘poate reita streamal de iesie cout de la eran spre un fgler sau un alk pro- lg! in mod asemanitor, se ponte redira stream de-inirare cin de a asta Cand wm program canta st proceseaza erorile crtice, mesajele de eroare nu pot Fredinjate de la ecrantl monitorului. In acest caz trebuie folosit stream-ul cert pentrt afisarea mesajelor. De exemplu, urmatorul program, USE_CERR_CPP afigeaz2 un mesa) folosind cerr include Incercaji s4 Compilalj $1 sii executati acest program, folosind operatorii de redirjre ai sistemului de operare, Vet sedea c& mu este posbi redirarea 5 Succes cu C++ ‘mesajelor scrise cu cer. Mal tarziu, tot in acest capitol, vel! examina iesirea prin buffer folosita de cout gi clog. aa =r: iNTELEGEM STREAM-URILE 170 ] | {in cel mai simplu sens, un stream VO este o suecesiune de| caractere, sctise pe ecran sau ctite de la tastatur, Fisierul anlet OSTREAMH defineste patra streamer VO: cou cy cem si clog. Strearm-ul cow permite afigarea rezutatelor i fcran sau pe dlspostivul de_iegre standard, In mod asemnator, cin realzeazd crea caracterelor de la tastlur8 [sau de la dispocttval standard de intrare. In sfrsit, cer si clog determina) Iprosramele si afigeze tesirea pe disposiival de eroare standard. Pentru a irea spre un stream I/O, se foloseste operatorul de extragere (<<), 1 | cout > nune>> prenure: ‘SA INTELEGEM STREAM-URILE DE INTRARE $I IESIRE (>), ca, ‘Multi dintre manipulatorii si funcfile discutate tn acest capitol corespund strearrvurilor de intrare si iesire. La examinarea fisierulul |OSTREAMH veti gsi unele definiii ce folosesc ios $i altele ce folosesc istream si ostrearn, Definite ce folosese fos corespund stream-urilor intrare $i iesire (de aceea apare pre- scuriarea jo). in mod similar, definitiile bazate pe istream corespund stream- urilor de intare, iar cele bazate pe ostream - streanurile de iesire. Prin exami- area definiilor stream-urilor se poate infelege mai bine flecare manipulator sau functie membru in Capitolul 11 se vor trata mai detaliatrelalleintre clase, CARACTERE SPECIALE Unul din programele precedente a folosit manipulatorul endl! pentru a genera 0 _secventi CRLF. (retut de.car_- avans hartie). in mod asemanaior, urmatorut pro ‘gram, THREELIN.CPP, foloseste un manipulator endl pentru a afiga lesirea pe 1: Tastatura si ecranul include ‘oid main(void) cout < “Successn << endl: cout < “with, << end?: cout ce “Cet void mat (void) cout < “Success” << endl << “With” << endl << "GHel” << endl: } in mod similar, un alt program prezentat anterior in acest capitol folosea caracte- rele \t pentru a genera tabulatori, Cand se realizeaza iesirea pe cout, cerr sau clog in streamul de iesire se pot folosi caracterele speciale prezentate in Tabela 1.2. Caraceral _ Semnifiea « ‘ert sau clopotel » Backspace v Inceputde pagina w Inceput define novs (ehivalent cu end) v Cariage tum Gneeputul inet curente) fra avand hare nefeed) “ Tebulator oizonta wv Tabulatorveetia v Backslash v Sern de itvebare y Apostrot hitimete ” Ccoracter mt ‘000 Vatoare in octal, 3033 : ‘uhh ___Vatoarenexazecial ca 6 1B Tabeis 1.2. Caractere speciale flosite cu cout, cert si clog, Succes cu C++ Urmatonul program, SPECCHAR CPP, foloseste aceste simboluri speciale pentru a sterge ecranul si apoi pentru a emite un semnal sonor prin difuzorul calculatorului, Pentru slergerea ecranului, tebuie s& fie incarcat driver-ul de dispozitiv ANSI, Prograsmul foloseste secventa speclald ANSI Ese[2J pentru a sterge ecranul Hinclude void maincvotdy { Corr << “\aSome error message\t\ K-11 0": 3 Dupa cum se poate vedea, programul foloseste caracterul \a pentru semnalul sonor si caracterul \t pentru a genera un tabulator. In Capitolul 11 veti invata um s8 crea proprli dumneavoasiré manipulator ce corespund acestor crac: lere speciale LUCRUL CU MANIPULATOR! Un manipulator de stream V/O este un element prin care se fitreaza iesirea unui stream /O. De exemplu, manipulator hex, oct si dec determina afigarea net valori in hexazecimal, octal sau zecimal. Urmatorul program, MANIPULA.CPP, ilustreaza modul in care sunt folositj acesti manipulatori. Hificlude void main(votat ‘nt nusber = 1001: cout << “Decinal: * << nurber << "\tHeradecinal: * << satbase(16) << number << endl: cout << “Decinal: * << setbase(10) << runber << “\tOctal: * << setbase(®) << runber << end: y Observatie: Dacd compilatonil pe care il folositi nu include manipulatoral setbase, pute(folosi manipulatorul setlosflags. De exemplu, pentru a selecta baza hexazecimalé, folosii setiosflags (Ios::hex). CONTROLUL LATIMII ZONEL DE ALINIERE Céteva din programele anterioare au folosit spai in interior sirurilor de carac- tere pentru a formata afisarea acestora. Pe langa aceast& metoda ,brutala de spatiere, programele pot folosi manipulatorul setw care specificé numarul minim de poziti ale zonei de alinere, Daca 0 valoare necesita mai multe carac~ tere decat numérul specificat in sett, atunci pentru afigarea ei vor fi folosite atatea caractere cite sunt necesare. Daca o valoare necesita mai puyine ca- ractere, atunci spali suplimentare vor finserate inaintea valor afigate. Spre de- osebire de manipulator dec, oct, hex si setbase prezentati mai inainte, manipu- latorul setw are efect numai asupra valoril urmatoare. Cu alte cuvinte, alinierea stabilta prin setw nu este permanent’, Urmatorul program, SETW.CPP, ilustrea- 24 folosirea manipulatorului setw: include include void main(void) ¢ int: for Gm 1:18: 14) cout << setw(i) << 1 <« setw(s) << 12 << setw() << 123 << endl: ) Deoarece latimea zonei de aliniere selectata prin setw influenteazd numat turmatoarea valoare afigaté, programul foloseste manipulatorul de céteva ori in aceeagi instructiune. La compilarea si execulia acestui program, pe ecran vor fi afigate urmatoarele: Cap Seni “sem” 5 (pSantene iueiz3 setw(i) m2iz3 setw(2) 10 1: Tastatura si ecranul qin Lie 1 setw(3) setu(4) Dupa cum se poate observa, dao valoare are mai multe caractere decat cele Eelectate de ser, ea va fl afigata cu toate caracterele necesare,[n cazul primel Tl de fesie, toate cele tei valor contin cel putin o cif. Ina doua lnie sunt locate dous caractere penirs fecare valoare, in a trea line - tre, at ina patra Tine - 4 earactere. Se observ clin uma line, valoarea 1 este precedaté de 3 spa, valoarea 12 - de doua spa iar valoarea 123 - de un spau. STABILIREA CARACTERULUI DE UMPLE! ‘Aga cum afi invatat, manipulatorul setw permite specificarea lagimii minime a zonei de aliniere. In mod prestabilit, stream-urile /O folosesc spatiile pentru ob- {inerea unei spatier corecte intre caractere. Cu ajutorul manipulatorului sei! Se pot specifica si alte caractere de completare a zonelor dintre valori. De ‘exemplu, urmatoarea instructiune dirijeaza strearn-ul cout pent a folosi punc- tul drept carecter de completare: cout Yeid main(void) € int: cout << sat 711 for (i= 1: 4 <5: 44) out << setw(i) << 1 << setw(i) << 12 << setw(i) << 123 << endl } Prototipul pentru manipulatorul setil se gaseste in fsierul antet IOMANIP.H, La. ‘compilarea si executia acestui program, pe ecran va aparea: C:\> SETFILL : ss M2123 112123 1.12123 eed nd212 Succes cu C++ (© ulilizare frecvent& a manipulatorulul serif este la crearea unui menits sau a tunel table de cuprins, dupa cum se vede in continuare: Cuprins Capitolul |, Iniierea in intirviesii cu tastatura. . Capitolul 2. Initierea in clase. Capitolul 3, Inifierea in figiere.... CCapitolul 4, Injierea in clase template Capitola 5 Intierea in mostenire. Urmatorul program, TABLE.CPP, ilustreazé modul in care mani ccreeaza tabela precedenta: Hinelude «iostrean. tr #inelude void main(votd) { cout << setfNC."): cout void maintvoid) eam 6 eset * Dupa cum se gle, sistemul zecimal anglo-saxon foloseste virgula in lou punctulut slinvers. -NR 12 | 1: Tastatura si ecranul PR fon Ci = 0: 1 < 10: H4) | ‘cout << Setareciston(#) <= 22,0 / 7.0 << endl oe ‘Asa cum se vede, programul cicleaz’ de la 0 la 10, folosind setprecision pentru ‘controlul nurndirului de cifre afisate. Prototipul manipulatorului setprecision este > ws >> camp: Succes cu C++ eee De exemple, urmatorul program, SKIL_WS.CPP, foloseste manipulatorul ws pentru ignorarea spatilor albe plasate inaintea textui ipa include #include void main(vord) € char text{128): cout << “Type in a word preceded by one or more blanks” << endl: cin >> ws >> text: Cout << "You typed 97 << text <¢ * endl; CONTROLUL INDICATORILOR STREAM-ULUII/O ‘Asa cum afi invatat, 0 parte din manipulator stream-ului YO rman activ) st dupa incheterea unel operaii de intrare‘iesie. De exemplo, manipulator des, hex sh oct selecteaza baza de afigare a valoilor numerice. Pentru a implementa acesti manipulator, stearurile YO au un cmp indicator (fag field) care. Specificd valorile curente ale parametilor. Un fisier antet defineste aceste valor, cca flind de tip enumerativ, dupa cum se vede mai jos: enn { skipws = 00001. eft = ox0002, right = 0x0004, ‘nterna) = 0x0008, 11 Skip white space during input 11 Left Justify: output 71 Right. justify outout 11 Pad after sign or base indicator dec = 030010, 11 Decimal base ‘oct = 0x0020, 17 Octal base. hex = ox004o, 17 Hexadecimal bese 1/ Use base indicator on output 71 Fores dectnal point for floating point 1/ Uppercese hex output W/ Add‘ te positive intesers 1/ Use 3.1415E2 floating notation 11 Use 314.45 Floating notation U1 Flush all streams after insertion I Flush stdout, stderr after insertion showbase = 0x0080. showpoint ~ 00300 Uppercase = 0x0200, showpos = 0x0400. setentific = Ox0800. fixed = 01000, unitbuf = 012000. stdio = Ox4000 y Prin folosirea manipulatorilor setios/lags, programele pot controla o buna parte Gintre acest indicatoriDe"exémplu, urmatorul program, 1OSFLAGS.CPP, fol * este indicator dec, oct, hex si showbase pentru a afiga un mumar in zecimal, ‘octal si hexazecimal 14 | | 1: Tastatura si ecranul include void main(vord) ‘ cout <« setiostlags( ios: showbase); cout << setinsflags( fos: idee) cout << “Id in decimal is." << 10 << endl: cout << setiasflags( ios: :oct) cout <€ “10 in octal is * << 10 << endl: cout << pe NE ees La compilarea si executia acestui program, pe ecran va aparea’ Ca\> TOSFLAGS tare 10 in decinal 15:10 10 in octal is 312 10 fn hex 1s Oa In acest can, indicator iosishowbase deans sear cout 8 prefiere sao ote or cle hexneca a Or. une cant pont neve ‘area mai multor indicatori simultan, Aceasta se poate realiza printi-o operatie OR (SAU) intre indicatorii dori, cum se vede in continuate: cout < include void main(votd) { cout << “Lowercase: ~ << hex << 265 <<" << 10 Lowercase: ff a Uppercase: FF A ALINIEREA REZULTATELOR LA STANGA SAU LA DREAPTA In mod prestabilit, stream-urile VO afigeaza tesirea aliniata la stanga. Prin folost rea indicatorilor ios:left§\ios:vight, programele pot controla alinierea iesiri, De fexemplu, urmatorul program, LEFTRITE.CPP, foloseste indicatoril mentionati penini a alinia iesiren ata la stanga, cat sila dreapla: Hinclude void main(voia) { cout << sec‘astlags(ios::fixed) << 128.48 << endl ‘cout << 12545,6789 FIXELOAT 123.450000 12345.678800 1.23a600e+02 .2aassuer0e Dupa cum se observa, formatul os:fixed dirjeaza stream-ul V/O pentru afigarea punctului zecimal tn pozitia sa actual, In timp ce indicatorul iost:scientifie dirjjeaza strearm-ul VO sa foloseascd formatul exponential. FORTAREA AF.SARII PUNCTULUI ZECIMAL ¢ Cand programele afigeazé rezultatele unor operaiii in virgulé mobil, nu fintotdeauna punctul zecimal este tiparit, in spectal cdnd rezultatele sunt exacte (fara parte zecimala). Sa consideram, de exemplu, urmatoarea instructiune: cout <<10.0/5 << endl: Deoarece rezultatul imparyril este exact, stream-ul /O poate tipari valoarea 2, in loc de 2.0. Daca se doreste si tiparirea punctului zecimal, se poate folosi Indicatorul ios::shoupoint, Urmatorul program, SHOWPOIN.CPP jlustreazd folosirea acestul indicator pentru fortarea afisarii punctului zecimal. include void maincvoid) cout << 10.0 / 5 << endl cout << setiosflags(ios::showpoint) << 10.0 / § << endl: y 7 18 Succes cu C++ La compllarea si execulia acestui program, pe ecran va aparea’ C:\> SHOKPOIN, 2 2.00000 FORTAREA AFISARH] SEMNULUI UNET VALORE in mod prestabilt,stream-uile YO afgeaza numai semnul valorilor negative. In funcile de scopul programilui, uneori este necesara afigarea semnultl plus in fata valorilor pozitve, In astel de situa, programele pot foosi indicator fos::showpos. De exemplu, urmatorul program, SHOWPOS CPF, ilustreaza folo- sirea acest indicator Finclude include void nain(voie) { cout <¢ <1) ee ee Gee eeQ ee ecb ee 10 << endl ‘cout << sotiostlags(ios::showpos): cout <1 cet ee Seen eeD eet eh eet ae 10 << end d Dupa compilarea si execulia acestui program, pe ecran va aparea: ccs\> sHomPOs 10 5.05.10 219-5 045 +10 Hinclude ~ characters” << endl: 3 Observatie: La contorizarea caracterelor unui string (sir de caractere), functia gcount include si caracterul CR (carriage return - retur de car) - adied, dacd introduce siral 123, valoarea lui geount va M4 Compilati $i executati acest program. Experimentatl funetia gcount introducénd siruri cu numar diferit de caractere. Avet| in vedere c& gcount include si caracte- nul de sfarsit de linie CR, << cin.geount() << 7 %CITIREA UNEI LINDE LA TASTATURA SAU DE LA STDIN Cand programele realizeaza operat de intrare folosind stream-ul de intrare cin, acesta separa valorile prin spati albe (spatii simple, tabulatori sau caractere sfarsit de linie). In functie de valorile pe care programele trebuie sa le introduc, poate finecesara citirea unei lini intregi de text, ca apoi parti ale acesteia sa fie relucrate, Pentru citirea unei linii de text, programele pot folosi functia ‘membru getline. Urmatorul program, GETLINE.CPP, foloseste funcjia membra getline pentru citirea unei lini de text de la tastatura. include ‘void nain(void) te char Tine( 122) ‘cout << “Type in a Tine of text and press Enter” << endl in.getlinetline, sizeof(1ine). 1°): cout << “First Vine: " e Tine << endl: in.getline(T ine, sizeof(Tine)): cout << “Second line: * << Tine: } Compilati si exacutati acest program. Dati la intrare o Serie de cuvinte separate de caracterul X Programul va afisa textul ce precede caracterul X pe prima linie sitextul ce urmieaz dupa X pe a doua nie. Observatie: Coracterul X in acest program este dependent de tipulliterei (case- sensitive). Litera micd 'x' nu va determina oprirea intrarii la primul apel at functiei cin.getline. De asemenea, pand la introducerea caracterului X, puteti tasta ENTER or‘ de cdte ori dorit férd a opri operatia de intrare ta primul apel al lui cin getline; aceasta se va tncheia la prima tastare ENTER dupa introducerea ccaracteralui X. ‘TOLOSIREA FUNCTILOR MEMBRU ALE STREAM-ULUI CIN ‘Asa cum s-a spus, cin este un obiect de tipul istream. De ‘aceea cin suporta mai multe func{i. Urmatoarea instructiu- ne, de exemplu, foloseste functia membru getline pentru a citlo linie de text de la tastatura cin.gotline (line, sizeof (1ive)): “in din figierul IOSTREAM.H, putett determina| cn 22 ‘Succes cu C++ -REALIZAREA OPERATHLOR DE INTRARE CARACTER CU CARACTER in functje de cerintele ce intrare ale unui program, uneor sunt necesare operat de introducere a céte unui singur caracter. In astfel de situati se poate folosi functia membmu get. De exemplu, programul urmator, YES_NO.CPP, invté ui- zalorul sé introdued un rispuns prin una din alterativele Y sau N. Programul foloseste functia membru ger pind cind intlneste caracterul ¥ sau N: #include void maincvoid) char letter: ‘cout << “Typa a Y or Wi: oof etter = etn. get0) 11 Read a character letter = toupper (letter): 11 Convert to uppercase }owhile (letter {= 7") BR (letter I= "N')): cout << endl << “You typed: “ << letter Frnclude TO_UPPER < TO_UPPER.CEP ANTICIPAREA URMATORULUI CARACTER LA INTRARE in functje de cetintele de intrare ale unui programm, uneori este necesara citirea tunor caractere pan la un anumit caracter, cu exceptja acestuia. De exemplt, S& presupunem ca un program citeste un fisier ce confine nume urmate de rnumere de telefon, ca mai jos: Joe Smith 555-1212 John Davis 222-2323 Betty Lou Johnson 333-3943 In acest caz, programul ar putea atribui caracterele ce preced numérul de telefon unei variabile de tip sit, Pentru a citi caracterele pand la un anumit caracter, se poste folosi funcjia membru cin.peek. Functia citeste un caracter din bulferul ce intrare, fara a4 scoate din buffer. Urmatorul program, 7O_DIGIT.CPP, va cere s4 introduceti cuvinte, urmate de un numar. Programul foloseste functia membru peek pentru a localiza prima cifra, atribuind caracte- tele care precec numérul unul sir de caractere denumit fine: Finclude Hinclude void main(void) : { char letter, string(12é]: int 1 = 0, done = 0: cout << “Type ina string terminated by a nurber* << endl: dof etter = cin.peek(): Af (1 isdigitcletter) stringCite] = cin.g2t( else one * 1 } while ((1 done) && (4 < sizeofstring))): stringCi] * WLL: cout << “String input: " << string << endl 23° 24 Succes cu C++ Observatie: Majoritatea programelor ce folosesc functia membru peek pot five- scrise pentru a elimina necesitatea prograrelor de a folosi functia, tmbundté- Jindwle astfelclaritatea. Dacd folosif in programe functia peek, trebuie sd aveti in vedere si modalitaji de a rescrie programele, READUCEREA UNUI CARACTER IN BUFFER-UL DE INTRARE Programul anterior folosea functia membru peek a stream-ului de intrare pentru a determina urmatorul caracter din buffer-ul de intrare. In functie de operatile efectuate de un program, uneori poate fi necesara plasarea unui caracter in buflerul de intrare sau plasarea in buffer a altui caracter decat cel citit. In astfel de situatii, programele pot folosi functia membru putback. Urmatorul program, PUTBACK.CPP, citeste caractere din buffer-ul de intrare, afigand numarul de ca raclere cite. Programul contorizeaz numai caracterele majuscule. La intélni- +a une’ litere mici, programul plaseaz4 Inapol in buffer majuscula echivalenta: Hinclude = 'a") ab Catter = °2")) ‘cin. putback(toupper (letter)): else if ((letter > 'A') Bh (letter = °2")) countLTetter = *A'Je# } while (letter = “\a"): for (= 0: 1 < 26: i) ‘cout. put (char) (*AT + 4D): 7 : cout <<” <© count] << endl: £ y ) Dupdcum se obser’, dar programul.intélneste 0 Werd mcd el foloseste iunctia membru purback penta plasa itera majusculé echivaenta ‘in bufferul 4e intrare. in acest mod, programul va contoriza nurmailterele majuscule. Tastatura si ecranul : Majortatea programelor care folosese functia membru putback pot ff rescrise fard a folosi aceastd functie, imbundtatindu-se astfel claritatea ‘acestora, Daca foiosit! in programe functia pulback e bine sd ud gdndi la modalitat de a rescrie acele programe. DETECTAREA i RSITULUT DE FISIER Capitotul 3 examineaza in detaliu operatile cu fisiere C++. Veti afla atunci c& sulte programe citese fisierele de fa inceput pana la sfarsit, folosind functia membru eof de detectare a sfarsitului de fisier. Cand scrieti programe ce folosesc redirectarea VO, putel} folosi funciia eof pentru depistarea sfarsitulul intrariiredirectate. De exemplu, urmatorul program, LINE.CPP, citeste dintr-o intrare redirectata si apoi afigeaza numarul de lini citite: include void main(votd) { oh char Vine( 266): | Tong: count = 0: ote (1 cin.eof) ‘cin. getTinetline, sizeof (Vine) count: y cout << “Lines read: uh _Dupa compilarea acestui program, << count << endl putetl rediria intratea, ase: * ‘Ge\e LINEENT. < LINECKT.CPP. Uires read: 15 Dupa cum se vede, acest program, ca $i altele prezentate In acest capitol, cicleaza pind la intdinirca efargitului de fisior. IGNORAREA CARACTERELOR DIN STREAM-UL DE INTRARE La realizarea operatilor de VO, pot exista situa cind se doreste ignorarea caracterelor din stream-ul de intrare, De exemplu, sa presupunem c& un program trebuie 58 citeasc& urmStorul fisier gi are nevoie numai de numerele de asigurari sociale’ ‘Smith,John —111-22.3333, Lewis, Bill 222-33-4444 Jones, Mary 333-445555 26 Succes cu C++ Folosind functia membru ignore, se pot ignora caractere din stream-ul de intrare. De exemplu, urmatoarea instructiune dirjjeaza cin s& ignore urmStoa- rele 10 caractere de la intrare: cin, tgnore (10): Programele pot, de asemenea, si dirijeze stream-ul VO pentru a ignora caracte- rele pana la intdlnirea unui anumit caracter, De exemplu, urmatoarea instructiu- ne determind cin sa ignore primele 10 caractere sau caracterele pana la litera A inchusiv: ein.ignore (10,.°A')s v ‘Inacest caz, cin va ignora cel mult 10 caractere. Cu alte cuvinte, dac’ litera A apa- re In primele 10 caractere, cin nu va mai ignora caracterele ce apar dupa litera A. CITIREA $I SALVAREA DIFERITELOR VALORI ALE PARAMETRILOR I/O Asa cum af! Invatat, stream-urile VO furnizeazs cétiva manipulatoi si funci ce permit controll unor parametti YO. De exemplu, manipulatorul senw permite definicea limi unui cmp de afisare, Cand programele folosese acesti manipi- lator penini a controla difrite valor ale unor parametri, poate fnecesara de- terminarea valorilorindicatorilor curen atfel incat programele sé poa f e- constitute mai taru, In asfel de situati, se pot folsi functile din tabela 1.3. pentru citrea valorlorcurente. Func membru Revultatul returmat fags ‘valoareaindleatoror eueny wien lajimea eémpuii curent de afgare ‘a caractral de completare precision ~valoarea precise curente Tabela 1.3. Funcyiile membru ale stream-ulul YO ce returneaz® valori ale paranetrilor de stare Urmatorul program, SHOWINFO.CPP, foloseste aceste funcli pentru a afisa valorile prestabilite ale parametrilor unui stream: include : void main(void { tong fags: Mags = cout. fags); cout << “Default flags: cout << “Default width: << hex <« flags << endl; << dec << cout.width() << endl: | | | 1: Tastatura si ecranul “cout << "Default FiNI: >*°<< cout. 110) << *e* << endl cout << “Default precision: " << cout.precision() << end y La compilarea si executia acestui program, pe ecran se va aflga: G28 SHENINFO. < Default precision: 6 ‘Si INTELEGEM PARAMETRIT STREANF-ULUI DB IESIRE C++ dispune de o serie de functii membru ce permit controlul spatieril sl formataril unui stream, Cand folosit aceste functii pentru a schimba o valoare de parametru, schimbarea rmane activa pana la terminarea programului sau efectuarea altei schimbari. Dac examinafifisierul antet folosit de compilator pentru defintile de stream-uri veti afla lcd aceste functii corespund variabilelor membru ale unei clase de stream V/O. La invocarea functiei, valoarea variabilel membru corespunzatoare este schim- bata. Ulterior, la realizarea unei operatii /O cu acel stream, operatia va folosi \valoarea stabilita a variabilei membru pentru controlul intr i FACILITATI OFERITE DE FUNCTILE MEMBRU ALE STREAM-ULUI DE IESIRE ‘Asa cum afi invatat, stream-urile de intrare furnizeaza céteva funetit membru pentru realizarea unor operatii VO specifice. Acest paragraf examineaza functii membru ale stream-ului de iesire cu acecasi finaltate. De exemplu, urmatorul program, PUTALPHA.CPP, foloseste functla membru put pentru a afisa pe ecran literele alfabetului, una cate una: Hinclude void nain(void) € be char letter: for (letter = letter <= "2": letter) La compilarea si executla programulul, pe ecran va aparea: ENS PUTALPHA «Eure ‘ABCOEFGHT KLANOPORSTUVWAYZ, Succes cu C++. Poate va intrebati de ce in programul precedent s.a folositfunctia membru put, in loc de cout, ca mai jos: for (etter "4° cout << letter: letter 4 + Tetteny) Daca in program variabila leter este declarata de tip char, se pot folosi ambele tehnici pentru afigarea literelor. Ins daca variabila letter este de tip int, atunci prin a doua metod’ pe ecran se vor afiga_numerele intre 65 si 90, in loc de literele A pand la Z. FOLOSIREA FUNCPILOR MEMBRU Th ALE STREAM-ULUI COUT Asa cum sa vazut, cout este un obiect de tip ostream, Ca| alare, cout suport mai multe func membru. Urmatoarea| instructiune, de exemplu, foloseste functia membru put} pentru serie un caracter la dispozitivul standard de iesire: cout.put(7):// seanal sonor prin difuzorul incorporat Prin examinarea definitie clasei cout din fisierul IOSTREAMH, se pot gist rapia| functile membru disponibile, prin consultarea listei de prototipuri, TESTAREA REUSITEI OPERATILOR I/O Fiecare din programele anterioare au realizat operatii de VO, presupundnd c& acele operatiis-au derulat cu succes. Cand programele scriu mesaje simple pe fecran sau citesc una-doud lini de la tastaturd, in mod normal pute presupune ‘ch operatille se incheie cu succes. Insé, pe masuré ce programele devin mai ‘complexe, ar trebui vericaté finalitatea operatillor, folosind functille membru 4g00d, bad, fail si rdstate. Fiecare din aceste func{i membru examineaza biti de stare din indicatorul de stare al stream-ului VO, pentru a determina dacé a avut Joc 0 eroare. In funclie de compilatorul folosit, valoarea si semnificatia biilor de stare poate fi usor diferits. Totus), dacé examinatifisierul antet al definitilor legate: de stream-ur, vet gst o defintle de tip enumerativ a acestor biti, ca mai jos: ‘enum to_state { goodbit = ox00 eofbit = Ox0l, 1/ Set 4 1/0 operations fave been successful © © 1/ Set $f currently at the end of the file faiTbit = 0x02, // Set if last 1/0 operation failed “ badbit = 0x04," // Set if an invalid operation was attenpted hardfan) = 0980 // Set 4f an unrecoverable error occurred, ; Fahd hl acienticts Pentru a vedea dacé a avut loc 0 eroare YO, programele pot testa difer stare. De exerplu, urm&torul program, TEST_10.CPP, foloseste functia membru fail pentru a determina dacd operatile VO sau incheiat cu succes: 28 1: Tastatura gi ecranul Hielude A:UPPER.CPP cen Inacestcaz,TEST_10 va tt coninutul ser FILENAME.CPP, seid majuscule echivalentefeciraisracter pe fsieral UPPER.CPP de pe urilatea A Dacd apare 9 eroare cand TEST10 cteste ser de intare sau sere sen de isie (de Pia, spat insuicient pe die), programa va fie un mesaj de eroae in steam ul fgieruutstandarc de eros se va termina, Deoarece programnele pot testa Corecttucinea opeatilor V0 In moe chismit, stearate WO definere sere de fxciamare ca un operator ‘ce detectenzi 0 operate UO nereusi Atel uurmtoarele instruct sun identice din pune de vedere funcional He cein.east0) if dein In cazul cand un stream YO intélneste o eroare, bitul de eroare rimane selat pind ‘cand se sterge indicatorul prin functia membru clear, curn se arata mai jos: i (cout. 10810) * © cerr << “Display sone error message” << endl 5 sout.clear(); Succes cu C++ Tn functie de modul in care un program manipuleazi erorile VO, se poate cere examinatea indicatorilor de stare in vederea determinarii tipului de eroare aparul, Pentru aceasta se poate folosi funciia membru rdstate, ca mai jos: 40. state = cin.rdstate 3 a Penin a infelege mai bine definiile acestor functii membru, puteti examina figierul antet folosit de compilator pentru definitile legate de strearr-urite YO. “SH INTELEGEM STAREA UNUT STREAM 1/0 La realizarea operatilor cu strearn-urile VO, se poate testa in! programe finalizarea cu succes a unei operatii folosind! functile membru ale clasei YO. Daca examinati fisterul antet) pentru definiile legate de stream-uri, veti afla ca stream: turile YO contin o varlabili membru de stare ai cArei biti ccorespund stérii curente a strearn-ului. Analizand biti acestel variabile, programele pot determina incheierea cu succes a operaliei VO anteri | ‘care. Majoritatea programelor, tolusi,folosesc funeji membru incorporate pen- iru a realiza aceste teste z INTRARI-IESIRI CU $1 FARA BUFFER ‘Streameurile VO cout si clog folosesc iesirea prin buffer, adicd jesirea ru este ‘aligaté decat cind buffer-ul se umple, programul se inchele, buffer-ul este golit intentional , sau, In cazul stream-ului cout, cand programul cteste din stream-ul cin. Urmatorul program, BUFFERED.CPP, scrie iesirea la cour si asteapta apoi 3 ‘Secunde pand la terminare, Cand programul ia sfarsit, buffer-ul de iesire este afigat, ca in urmatorul exemplu: Finelude void main(vosd) € ‘eine t start_time, current_tine: cout << “HeTI0 G++ world!” << endl: timecestart_time); wt ‘ine(current_tine): while ((current_ tine - start tive) < 3): 3 Sb Bugee BS Programul foloseste functia time pentru determinarea timpulu introduce o intarziere de 3 secunde. 30 | | | | | | | curent si 1: Tastatura si ecranul GOLIREA UNUI BURFER DE IESIRE fn functie de operatile efectuate de program apar situatii cand buffer-ul de jesire trebule golitinainte de a se umple, inainte de incheierea programului, 2 ‘sau inainte de a realiza o operatie de intrare. in astfel de situalii programele pot : folosi functia memoru flush. De exemplu, urmStorul program, FLUSH.CPP, scrie tun mesaj la cout, face o pauza de 2 secunde, goleste stream-ul de iesire §/ apot ‘mai intirzie 3 secunde pan la incheiere: Finelude Hinclude yeid main(void) i ‘tine t start tine, current. tine cout << “HeTlo Or herd!” << endl z ‘ine(astart. tim): of © tme(Bcurrent. tine): }ovwhile ((eurrert. tine - start tine) < 2) ‘cout. usti): ‘tine(Qstart. tire) oo { ‘vime(current. tine): }owhile ((current-tine - start tine) < 3): cout << “Done!" <¢ endl: : y Jn Capitotul 11 voli aprofunda stream-urile /O prin buffer cand veti examina clasele sireambut i lebuf. FOLOSIREA FUNCTILOR MEMBRU PENTRU CONTROLUL INDICATORILOR DE STREAM I/O Aj invétat ceva mai devreme, in acest capitol, cum se controleaza iesirea unvi stream /O folosind manipulatoriisetiosfags si resetiosflags. Pe langa acesti ma- nipulatori, progranele pot avea un control mai precis asupra parametrilor aces- tot indicator folosind funcjille membru ale stream-urilor VO ce vor fi discutate in continuate. De sxemplu, urmitorul program, [OFLAGS.CPP, foloseste functia ‘membna flags pert aligarea valorilor parametrului indicatorului de stream: Hinclude 32 Succes cu C++ votd taintvord) cout << “cout Starting flag settings: * << hex < cout. flags() <© en cout << settosflags(os::stonbase) cout << "eout ending flag settings: * << cout. flags() <« endl: y “ Dupa compilarea si executla acestui program, pe ecran va apdrea un rezultat ‘dependent de compilatorulfolosit, avnd urmatoarea forma generala: 2\ IOFLAGS. g : ‘cout starting flag settings: 1 cout ending flag settings: Oxcl Folosind functia membru flags, un program poate salva valorite unui diferite momente, pentru a putea fi ullerior readuse Ja forma initial’. De fexemplu, programul SAVEFLAG.CPP, foloseste functia membru flags pentru a citi valoarea curenta a unul indicator $a 0 restabili ulterior. Hinclude Hinclude SAVEFLAG Hexadecimal values: ff a Decinal values: 255 10 Pe langé folosirea functiei memibru flags pentru configurarea indicatorilor stream- Urilor VO, programele mai pot fos! si functle membru set si unset. Pentru a crea sia sterge parameti indicatorilorfolosind aceste doua funciii membre, trebuie cu- ‘Roscut ili ce corespund flecdrut indicator. Prin folosirea tipulul de enumerare al in- dicatotilor prezentati anterior In acest capitol, se pot determina valorile corespunzé- toare ale biflor. De exemplu, urmatorul program, SETCLEAR CEP, foloseste Functile ‘merribru seff siunsetf pentni a crea’ sia Sterge indicatoriistream-ului VO: Finelude 80): // Clear the base display = gout << hex <= 255 <<" "<6 10 << endl: d Programul foloseste functia membru setf pentra a activa afigarea in bazii hexa- zecimals, Dupa ce afigeaz dou’ valori, programul foloseste functia membru lunseif pentru a dezactiva afigarea in baza respectiva. La comnpilarea si executia prograrmului, pe ecran va aparea: EW SETCLEAR tire Ont O33 ffa REZUMAT Fiecare program pe care il crea indiferent de destinata sa, va folosi operat de intrare sau iesire. De aceea, injelegerea stream-utilor VO si a posibiltailor Jor sunt esenijale pentru succesul in programarea C++. inainte de a continua, in Capitolul 2, asigurat-va c& al invatat urmatoarele: ¥ Imaginea optima a unui stream VO este o serie de octeti ¥ Compilatorul foloseste un fisier antet pentru a defini strearn-urile YO - ios, istream i ostream, precum $i functille $i variabilele membru. Ti- Paritio copie a acestui fisier sI studiati-o cu atentie. ¥ Operatorii de insertie (<<) si de extractie (>>) permit programelor ‘SA introdued si sd extraga caractere in/din stream-ul de VO. Y Manipwlatorii sunt elemente pe care le puteti plasa intr-un stream de intrare sau de iesire pentru a controla formatarea W/O. Fisierul antet IOMANP.H defineste manipulator disponibitt. Y Cand un program foloseste un manipulator pentru a configura formaterea unui stream, C++ stabileste valoarea bitilor din cémpul indicatorului Ge stream ce controleaza configurarea. Pentru a intelege mai bine acea configuratie de bit, consulta figierul antet folosit de compilator la definirea stream-uior. ¥ Streamurile de intrare/iesire contin diferite metode (funciii) ce per- ‘mit coatrolul formatului iesirt sau realizarea unei anumite operatti VO. Compilatorul defineste prototipurile functilor membru ale streamului int-un fisier antet, ‘ ¥ Streamuurile de iesite cout si clog realizeazi Iesirea prin buffer, cea cee inseamna c& iesirea este scris& numai atunci cénd buffer-ul se ‘umple, programul se incheie, programul goleste bulfer-ul, sau, ccazul lui cout, cind programul realizeaza o operalje de intrare. 33 foare adauga concepte pe baza inform: tet! invata pe rand pirile importante ale notiunii de obiect. Ca si mai inainte, trebuie sa aveti rabdarea de a experimenta programele prezentate prin schi Fut, vel incel mai simpli sens, un obiect este un lucru. Un caine, o carte, ct ~~ puter, toate sun: obiecte. in trecut, programatori isi concepeau programele ca pe liste lungi de instruc{iuni pentru realizarea unei sarcini specifice. La crearea CAPITOLUL 2 IMODAREA CU Este posibil sa puteti scrie o multime de programe C++ fara a intelege cu adevarat sau fari a folosi obiecte, desi obiectele si clasele sunt esentiale pentru utilizarea la masimum a limbajulul, Dar nu va speriati! Acest capitol incepe cu it pasi $i prezinta regulile de baz ce trebuie cunoscute. Capitolele urmé- F prezentate aici, In acest mod, pu Chiar si ibarl smple, puteti invata foarte mult. La incheierea terminarii capito- injelege urmatoarele: + Ceeste un obiect + Cum un program complicat, de mari dimensiuni, este mai ugor de conceput si de redactat folosind 0 abordare orientata pe object in Jocul uneia conventionale, orientata pe functie ‘+ Cum un obiect poate economisi timp gi efor . + Ceeste mostenirea ‘+ Avantajulfolosiri objectelor + Cum se creeazi un obiect + Avantajele si dezavantajele functillorinfine + Cum se folosese doud variabile diferite cu acelasi nume in acelasi program ‘+ Ce sunt functile constructor si destructor de clase + Cum se atribuie valoarea unui obiect altui object PRIMUL CONTACT CU PROGRAMAREA ORIENTATA PE OBIECTE un com- 35° 36 Succ es cu C++ de programe orientate pe obiedte, accentul se pune pe obiectele componente ale programutu Sa presupunem, de exemplu, c& scrieti un program ce implementeaza simplu lun procesor, Dac vi gandila toate functie realizate de un procesor de texte, vel fi repede coplesit de acestea. In schimb, daca va imaginali procesorul de cuvinte ca o colectie de obiecte distiete, programul va deven! mai putin intimi- dant, In figura 2.1 sunt iustrate obiectele principale ale sistemului de procesare de texte. [Veteare oo crogates ‘rie Figura 2.1. - Structura unui procesor de cuvinte ca o colectie de object. Pe masurd ce examinati flecare obiect, vet descoperi ca acesta este, de asemenea, compus din obiecte, cum se arata in Figura 2.2. nd incepeti sa identificati obiectele din sistemul dvs., veti vedea cé diferite Arif ale programului folosese acelasi ip de obiecte. De aceea, scriind programul vostru in termeni de obiecte, veti putea usor (si repede) 58 refolositi codul scris pentru o anumita secven{a intr-o alta parte a programului, sau chiar in alt program. In aceasta rezida o parte din puterea limbajului C++ Primul pas in crearea programelor orientate pe obiecte este de a identifica obiectele ce formeaza sistemul. Pentru a intelege mai bine cum se identifica obiectele sistemului, puteti face referintS la urmatoarele cérfi de analiza si prolectare orientate pe oblecte: + Object-Onented Design and Applications - Booch, Benjamin/Cummings, 1991 + Object-Oriented Analysis, Coad & Yourton, Yourdon Press, 1990 + Object Data Management, Cattel, Addison-Wesley, 1991 + Object-Oriented Reuse, Concurrency, and Distribution, Atkinson, Addison-Wesley, 1991 + Object-Oriefted Mettiods, Graham, Addison-Wesley, 1991 “ + An Introduction to Object-Oriented Programming, Budd, Addison- Wesley, 1991 2: Clase si obiecte + Object-Oriented Software Construction, Meyer, Prentice-Hall, 1988 + Object-Oriented System Analysis: A Model-Driven Approach, Embley, Kurtz and Woodfield, Yourdon Press, 1992 Figura 2.2, Idemtficarea obiectelor adijionate in cadrul procesorului de cuvinte. Dupa identificarea obiectelor, trebule sa determinati scopul flecérui obiect. Pentru aceasta, ganditi-va la operatile realizate de un obiect sau la operatiile efectuate pe acel obiect. De exemplu, daca fisier este un obiect, un program poate copia, sterge sau redenumi fisierul. Este important de observat 4, in general, aceste operat se aplicd fiecdrul fier de pe disc, indiferent de continu- {ul sdu, Aceste overatii vor deveni funcfile membru ale obiectului, pentru care ulterior veti scrie funciii C++ in programul respectiv. Apoi trebuie identificate informatile despre obiect. In cazul unui obiect fisier, trebule cunoscute numele fisierului, dimensiunea, gradul de protectie, eventual data la care fisierul a fost creat sau modificatullima oars, Aceste date vor deveni variabile membru ale obiectului, Conceptual, obiectul fisier se poate vedea can Figura 2.3. ee 37 - Succes cu C++ Tigler =} uml obec epee steere 1 funchile membru ale obiectui imensione Le cariabioe membeu ale Proocte sbieculu arorens date Figura 2.3. Funcpiile $i variabilele membru ale unui obiect fier. SH INTELEGEM PROGRAMAREA ORIENTATA PE OBIECTE | = Programarea orienta pe obiecte este bazaté pe scrierea de | programe cu referize la obiectele ce intra In componenta| tunui sistem, fn cadrul unui sistem, obiectele memoreaza| Lipurispecitice de informati i executa operat specific pe| acele informati. Primul pas In crearea unui program orientat| | pe obiecte este identificarea obiectelorsistemului, informa- [bile de baza referitoare la fiecare obiect si operaile realizate pe obiecte. La |scrierea primelor programe in C++, constructia lor se va opr, probabil, alc. P| | masura ce deveni mai experimentat, vei cSuta rela intre obiecte ce vor per- | mite constructia unor obiecte noi dn altele mai vechi. Pentru moment, ins, daca |cineva va cere sA defini un obiect C++, spunelile pur si simplu c un obiect |reprezinta o entitate alumi reale, poate contine date (Variabile membru) si are un {set concret de operati unctii membry) ce se efectueazd asupra acestora Uneori este necesara afisarea sau tiparirea unor fisiere; alteor, fisierele contin. programe executabile de care aveti nevoie. Ca atare, la defintia obiectelor trebuie adugate metodele de efectuare a operatilor respective, ceea ce nu este gresit.Totust, exist o varlan(a mai bund de a prelucta cazuile speciale. De exemplu, daca fisierul contine un document, conjinutul acestui fisier poate fi tipatit, operatie care nu ar avea sens dacé fisierul ar confine un program execu- tabil; in aceasta ultima situalie execufia continutului fisierului este operatia dorita. La incercarea de a executa conjinutul unul fisier document va rezulta 0 eroare, Solutia consta in identificarea a doud noi clase obiect, denumite docu- ‘ment si program, O modalitate de a crea aceste noi clase este adaugarea com- ponentelor respective la fiecare clas, aga cum se araté in Figura 24 38 2: Clase si obiecte dosumont program wopiere ‘copiere stergere stergere Federumire afgare dimensiune protecte ‘dimensione pratecie amprenta date amprenta date sistem de operare format Figura 2.4. Crearea ior clase document si program independent. Dupa cum se peate vedea, la obiectul document se adauga functjile membre display si print si variabila membru format (care specifica formatul inter al documentului, cum ar fi Word sau WordPerfect). in acelasi mod, la obiectul program se adauga functia membru run si cémpul sister de operare, care specifica daca programul ruleazi sub DOS, WINDOWS sau UNIX. “Aceste doua noi clase practic dubleazé clasa fisier definita anterior. De aceea 0 solulie mai buné este de a consirui cele doud clase bazate pe clasa figier, cura se aratd In Figura 2.5. Figura 2.5. Crearea noilor clase pe baza clasei fisier Céind programul dvs. construieste o clasti derivata dintr-o alté clasé, noua clasa mosteneste funeiille $i variabilele membru ale clasei de baza. in cazul claselor document si program, obiectele create cu aceste clase pot sa foloseascé nu 39° Succes cu C++ umai proprile functil si variabile membru, ci si pe acelea ale clasei fiser. in acest mod, programul dvs. poate s& execute cu usurinfé afisarea, tipdtirea, copierea, redenumirea sau stergerea unul fiser document, ‘SA SIMPLIFIGAM DEFINITIILE UNEI CLASE Pe masurd ce definiticlasele, incercati s& dati definitilor un} caracter general. Cu alle cuvinte, variabilele si functile ‘membru care apar in clasa de baza trebuie sa fie folosite de fiecare din clasele derivate (constnuite) din aceasta. Daca| teste nevoie sé adéugati la 0 clas mai mule variabile i functii membru, puteti defini o alté clasa, mai specializata bazald pe clasa generala. Constructja claselor in acest mod este esenta conceptului de mostenire a claselor, concept ce va fi tatat in detaliu in Capitolul 4. S-ar putea s& va miraji de ce e nevoie de acest procedeu. Primul motiv pentru folosirea mosteniii este refo- losirea, adica posibiltatea ca un program sé foloseasca codul scris si testat pentru alt program. De exemplu, s4 presupunem ca ali creat clasa fisier pentru un program de buget, intrucat clasa exist, aceasta poate fi rapid folosité in interiorul ‘unor programe noi. Existenta unei clase nu numai c& diminueazd efortul de programare, dar reduce si volumul testarllor necesare, intrucat functile membra ale claseifisier au fost testate siverificate anterior pentru programul de buget. ‘Si INTELEGEM MOSTENTREA Mostenirea este capacitatea unei clase derivate de a mosteni funcyile si variabilele membru ale unei clase de bazd cexistente. Pe masurd ce identifcati si examina} obiectele ce| ‘compun un sistem, veti gisi deseor relat si asemanari inte| obiecte. in multe cazuri, aceste relalii va permit s construiti tun ohiect din altul, care confine toate metodele originalulul. Cand proiectati clasele obiect, Incercati s& dati claselor un caracter cat mai general, Dac& numrul functilor si variabilelor incluse In efinitia unei clase creste, atunci posibiltatea de a refotosi acea clasé, sau de a| deriva alte clase din aceasta, scade, ING! ERIA PROGRAMELOR $I FOLOSIREA OBIECTELOR De ce ar trebui sa ne bazém pe obiecte In activitatea de programare? Exist cativa termeni de inginesla programelor care sunt folosii frecvent:pentru a deserie acest lucru, Cu toate c& existé dezacorduri in domeniul ingineriei de programe in privinga folosiri optime a obiectetor, sunt clar recunoscute cateva avantaje oferite de acestea: 40 | J 2: Clase si obiecte Usurinta proiectarit $i refolosirii codutui. O data ce codul func- sloneaza corect, folosirea obiectelor mareste posbbilitatea de a refolosi codul creat intr-o aplicatie pentru o alta aplicatie. Flabilitete crescuta. Deoarece bibliotecile de obiecte au fost anterior testate, folosirea codurilor existente (de lucru) va Imbu- nata{ifiabiltatea programulul, Usurinta intelegerit. Permitand proiectantilor si programatorilor 8 se concentreze asupra partilor componente ale unui sistem si fumizind un cadru in care proiectaniii pot identifica obiectele, operatille efectuate cu acestea precum si informatile pe care un object trebuie sa le contind, ulilizarea obiectelor ajuta programa- tori si nteleagé componentele importante ale unui sistem. Grad inalt de abstractizare. Abstractizarea permite programato- nilor sa aibé o vedere de ansamblu, adic s4 ignore ansamblul temporar detalile nesemnificative sis lucreze cu elementele de sistem ce sunt mai ugor de infeles. De exemplu, prin concentra- rea asupra obiectelor procesorului de cuvinte din exemplul ante- rior, imp ementarea acestula a devenit mai putin stresanta, Grad ridicat de incapsulare. Incapsularea grupeaz’ toate partile unui obiect intr-un modul compact. De exemplu, clasa figier def nitd tn exemplele anterioare combina funcii si campuri de date cu care atogramul lucreaz& intr-un fsier. Programatorul care I ccreaza cu clasa fisier nu trebuie s& cunoasca fiecare component a clasei, ci numal cum se foloseste clasa in program. Clasa, la randul ei, include toate componentele necesare, Ascunderea informatiel. Ascunderea informatiei reprezinta capa- citatea unui program de a trata 0 functie, procedurd, sau chiar un object, ca pe o ,cutie neagra", adica de a le folosi in anumite ope- ratii fara a cunoaste structura lor interioara. in Capitolul 1, de exem- plu, prugranele au folosit oblecte tip stream YO pentru intrare s1 iesire, férd a necesita injelegerea modului de functionare a stream-urilor VO, Pe masura ce vom examina conceptele de programare C++ In aceasté carte, vet} invata care sunt legaturile dintre aceste concepte si definitile de mai sus. SA iNTELEGEM OBIECTELE $1 CLASELE in decursul discutiei precedente, termenil obiecte si clase au fost folosi foarte “vag. In’general, 0 clasd furnizeazi un sablon folosit de program la crearea obiectelor. De exemplu, clasa fisier descrisa anterior specifica variabilele si funcyile membru ce vor Fi folosite pentru obiectele fisier pe care programul le va crea ulterior. Un object, agadar, este o instanfa (instance) a unui gablon de Al Succes cu C++ clas, Cu alte cuvinte, un obiect este o entitate, un exemplu specific, un articol cu care programul lucreaza, Definitia unei clase este similard unei definitii de siructurd in C. De urmatoarele instructiuni definesc clasa fgier: exemplu, class file ( public: char fiTenaneC64]; Tong size: unsigned protect ion: Tong datet ise: ‘int copy(char *target_naze): ‘nt renane(char *target.nane): int delete. filevotd): h Dupa cum se poate vedea, efiniia clase! indic&functile si variabilele membra Observati eticheta public ce apare la inceputul clase. Singurul mod in care prosramele pot avea acces direct la membrul une clase, fe aceasta functie sau Yariabila, este ca acel membru sa fie precedat de eticheta publi, Mat trziu, in acest capitol, vellinvaia cum sa foloslietichetele public si private pentru a Conirola modul in care programele pot avea acces Ia membrt unei clase. In Capitol 4, vei invja cum clasele conciijonate folosese eticheta protected pentru a furniza o cale intermediara de acces la membri. Deocamdatd, ins, pasa eticheta public la inceputal fiecdrei clase; astfelto{i membri casei vor eveni disponibiltn tot programul. © clasé defineste un sablon pentru creareauiterioard a obiectelor.Clasa insisi nu creeaza un obiect. Pentru crea un obiec, se declara variable de tip obiect, ‘cum este artat mai jos: void main(void) fe file source, target: // Declare two file absects 17 Other statements here } ‘DIFERENTA INTRE CLASE St OBIECTE Dacé citi articole gi cérti despre C++ si programarea orien- tatd pe obiecte, veli Intalni termenti clasd si obiect. O clasd fumizeazd un sablon ce defineste functiile $i variabilele’ membru necesare obiectelor avand tipul clasei. Un obiect, pe de alté parte, este o instanfd, un exemplu concret, de fapt! © variabild obiect. O clasa trebuie definita Inainte de decla-| rarea obiectulul, Pentru a declare 0 variabilé obiect, speci variabilei obiect, ca mai jos: iicati tipul clasei, urmat de numele Procesul cre unui obect este adesea denumit instantena und |crearea unei mos're de obiect, Ke ache nuse_clasa —nume_obiect: ANALIZA UNUTEXEMPLU COMPLET Cel mai bun miloe de a inflege clase gf cbectele C++ este de a crea un program spl, Umer progam, NOMIESCP, creed elas dvr movie apol creesza 2 obiecte de tip movie, cu humele histbe wt secoler Programul defineste clasa dupa cum urmeaza: aes ee class novie Variable membra public: " oe sesie ee char first start]: char second stari64]; void show movie( 01d) vofd initial ize(char *nane, char *first, char *second) Func memos Dupa cum se poate vedea, clasa movie foloses i a vedea, clas movie floseste tel variable membru i dou func{ii membru. Dupa definitia cle i, prc i nia clase, program trebue i deffreasl net membru show_movie $i initialize, astiel: ae Nei move: show movie ‘ cout << “Hovie rane: cout << “Starring: = endl <= andl; 7 << name << endl: << first star <<" and “ << second star << Wold movies:inttial:ze(cher *movie name, char *first, cher *second) strepy(naze, movie nere); strepy(first star, first): stropy(second star, second) Definiva functitor clasei este asemanat i 4 este asemanatoare definite! functifor standard ‘existand totusi doué diferente. Mai intai, numele functii ‘sunt : « fumele clasei si de simbolul " lnailor sunt Drecedate de Nume cls ee wid movie: :initialiae(char movie nane, char *first, char *second) ume tanto 43 Succes cu C++ jn al doilea rand, instructiunile din corpul unei functi ale unei clase pot face referin{é directa la variabilele membru ale clase: void movies;initiel ize(cher *movie_nane, char *first. char *second) strepy(rane. savie nave): strepy(first_star, first) strepy(second star, second) > No sure vasa net ete Name membriclasd Urmatoatele instructiuni implementeaza programul MOVIES.CPP: snclude void novte::show novi void) sa eee nam cc pirat str ce 2 and“ <¢ second star eat ee eat } void novte:sinitfalize(char movie name. char *first. char *second) { strepy(nane, movie name): strepy(first star, first) Strepy(second star. second) vols sain(votd) novie fugitive, sleepless: fugitive. nitialize("The Fugitive", “Harrison Ford”, “Tomy Lee Jones"): : sleepless, initsalize("Sleepless in Seattle “Wag Ryan”) “Toa Hanks”. fugitive.shew movie” sleepless. show movie() } 44 2: Clase si obiecte Dupa cum se poals vedea, programul creeaza dou’ obiecte de tipul movie: ume elas povle fugitive. sleepless; hie ele ‘Accesul la membriiunei clase este asemanator accesului la componentele unei structuri in C: se specific’ numele obiectulul, urmat de operatorul .’ si de ‘numele membrului corespunzator. De exernplu, pentru a apela functia initialize, obiectul fugitive fcloseste operatorul ‘si numele functiel membru, cum este aratat mal jos: Name obiect ramet fete ee fugitive. initial ize(“The Fugitive", “Harrison Ford", “Tomy Le eres") Na func In acest caz, progamul a folosit functia membru initialize pe variabilele membrs ale clasel, Mai tirziu in acest capitol vel folosi ru a inijaliza invata cum 8 i functiile constructor pentru a iniffaliza variabilele membru intr-un mod ‘maf natural CAND SE FOLOSE! CLASELE $I CAND STRUCTURILE —T {= JP Daca ati programat in C, probabil ati recunoscut faptul c& ‘S> —_sintaxa pentru lucrul cu clase este similar cele foloste in C Pentru structuri, V-afi putea intreba, cAnd trebule s& folositi clase, si nu structuri sau uniuni. Dupé cum sti, acestea permit programului sa memoreze date dependente, Progra- mele dvs. ar trebui sa foloseasca clase ori de cate ori asupra datelor au loc opera concrete. De exemplu, dacé avetinevoie de 0 ats, atunct pute loi srctura. Dar dacd dorf ca programa sa formateze sist afigeze daa 8 weacd data intr ger, au s& compare doud Cate, este ecesarautizarea nei clas, Silay, daca trebue sf opal te o stuctra euniune, decisie tobe hat in Rune le numaal Ce val pe cae suture Ge date congine un moment dat In slg, inl cont ca, mod presablt, membri uel clase sunt de tp priate, lar mem une! unr sau strat sunt eetippublc Daca experimentatistructurile din C++, veti descoperi c& ele suport multe din. Jconceptele clasei din C++, precum date publice si private, functii membru etc. Cao regula, daca creati obiecte, atuncifolositi clase, ACCESUL LA MEMBRII UNEI CLASE ‘(In progiamul precedent, ati folosit operatorul de acces pentru a apela funetille membru initialize $i show_movie. Cand programul plaseazi membrii 'unui obiect dupa eticheta public, el poate avea acces la membrii acestula 45 Succes cu C++ : Clase si obiecte GAP PUBLIC Hinclude class movie { Net ‘char namef 64]: char first_start64]: © char second star {6d void shaw movie( void) Declarei de func ‘membru ining cout << “Movie nane: "<< name << endl: cout << "Starring: << first_star << " and " << second star << end] <2 endl: } void initialtze(cher ‘eovie_nane, char *first, char *second) a { strepy(nane, movie_nane) Declare e functi strepy(first star, first ————— ‘membeu inne strepy(secone star, second 2 ) Un avantaj al declararii functiilor membru inline este acela ca intreaga clas ocupd un loc compact in program. Din pacate, folosirea funcyilor inline in acest ted mareste dimensiunea 31 complextaten definiilor clase. Mat simphu =pus, cu cat definita casei devine mai mare, co atat devine mai dificil de inteles. In Plus, codul pentru functiile inline nu este partajat Intre tipurile de obiecte Sirilare, asa cum se va vedea in continuare. Cand se definesc functiile membru in afara clasei, compilatorul C++ creeazio copie a corpului functiei ce va fi ulterior folosita de fiecare obiect al acelei clase. Cu alte cuvinte, dacd se creeazi 1000 de obiecte, fiecare obiect va folosi o singura copie a codului functiel. O astfel de partajare a functiei este indicat deoarece reduce semnificativ consumiul de memorie al programult 49 Succes cu C++ DEFINIR LOR MEMBRU IN APARA CLASEI | Cénd defini functile membra avell doud posibilta. Mail ESZIE ia putt ett nie inne in terol clase, ase >= i. in al © neat instructiunile functiei s& apara in definitia clas: doilea rand, puteli defini funcille In afara clasei, In majorita- tea cazurilor, aceasta este varianta optima, pentru a reduce Baclude PRIVATE Movie rane: The Fugitive Starring: Harrison Ford and Tomy Lee Jones Movie nane: Sleepless in Seattle Starring: Ton Hanks and Meg Ryen S& observam ca acest program nu mal afigeazd mesajele programului prece- ‘dent PUBLIC.CPP: votd main(void) novie fugitive, steepless: fugitive. initialize("The Fugitive". “Harrison Ford” “Tomy Lee Jones"): . sleopless. initial ize("Sleepless in Seattle”. “Tom Hanks’ “Weg Ryan”) The last two mavies I've watched are: 7 << fugitive.nane <<" and * << sleepless.nane << endl: cout << cout << “I thought " << fugitive. first_star << "was great!” << endl d Deoarece variabilele membru nu mai sunt publice, programul nu mai poate avea acces direct a acestea prin operator‘. Daca se dorese accesul la aceste variabile, trebuie create funetii membru special in acest scop. in cazul ‘cand credeii ca scrierea unor astfel de funciii membru e prea dificil si preferati accesul direct, nu faceff allceva decat sa marti posbilitatea aparitiei unor UI UNEI CLASE Sq INTELEGEM MEMBRII DE TIP PRIVA nd deca last, pute dein membre ca pubic eu priate Sau protected, cum vet aan Captotl, Memb Pubes ure ase sunt csponibi nt prota lesind hovel oblectu operator puns (ease member) sau opeatonl ae Indhecare (ase p-smembar. Memb prin Tunetite tembru ale clasei. Prin declararea intr-o clasd a unor membri 54 = private, ai ynel clase, pe de alté parte, pot f-utlizati numaite , 2: Clase si obiecte _ [clase sunt de tp priate Memb pubic se pot specifica scrnd in sla br] echeta publ, Dac ulleior se deste declaarea unor membr pricte e+ | bul inseratéecheta private, cum se aratan continuare: Jelass some class { public: void sone_function(cher *parareter); void Sone_other_functionCint a, int b. private: ' | | Sy tenonae | ©) | a te we: Mente pat | char petoartiag; | y | in acest caz, functile membnu ale clasei sunt publice, in timp ce variabilele| membra ale clesei sunt nonpublic. Tous, n funciie de class, pot exsta func rembre nonpublic, sau variable membru publice. a proiciarea castor ie bule determinat care dintre membri tebule sf fie de tip public, si care trebuie si ramand de tis private. ‘SH INTELEGEM CAMUFLAJUL INFORAMATIED Cemuflajlinformatiel este procesul de proiectae a func lor sata claselor dreptycuti negre”. Cu alte cuvinte, pentru a flo o fun sat o clas, programatorl nu treble <8 cunoascd toate amdnuntele inteme de funeionare ale cute, ci mai degraba operatiarealzaté de cutie «i modelul de] inet cu cia In progam C++, menby np ai unel clase realizeaza camuflajl informatie 1 | ‘SA INTELECEM CONSTRUCTORI $1 DESTRUCTORI DE CLASE Cand se creeazi obiecte, este céteodata nevoie de a aloca memorie pentru zonele tampon (buffers) folosite de obiecte. Si presupunem, de exemplu, c& hucrati cu un object figier care memoreazé numele fisierului intr-un gir de Caractere. Cand creati obiectul pentru prima data, veti dori ca obiectul s& aloce memorie in mod dinamic pentru a memora sirul de caractere, Mai tarziu, cand obiectul va fi desfintat, veti dori sd eliberati memoria alocata. Pentru a ajula Programele si realizeze asttel de operatil de fiecare data cand un obiect este Construit si apot distrus, imbajul C++ introduce funciille de tip constructor si destnictor. O daté ce v-ati insusit acesti termeni, veti vedea mai larziu ¢4 un Constructor nu este altceva decat o functie ce se executa automat de fiecare data cénd creati un obiect, iar un destructor este o funclie ce se executd automat cand ob ectul este distrus. 55 56 Succes cu C++ Ai folosit mai devreme, in acest capitol, funcjia membru initialize pentru a iniyaliza varibilele membru ale oblectelor apartinand clasel movie. Folosind 0 functie constructor, puteli elimina necesitatea ca programele dvs. sa apeleze functi ca initialize. in schimb, la crearea obiectulul programele vor specifica pur sisimplu valorile parametilor, ca mai jos: novie fugitive(“The Fugitive", “Harrison Ford”, “Tomy Lee Jones"): novie.sleepless("Sleepless in Seattle", “Ton Hanks", “Mog Ryan"); La randul su, C++ va apela automat functia constructor. in cadrul constructo- rului, pute{iatribui parametrii cémpurilor membru, la fel cum ali facut cand att folosit initialize. O funetie constructor este specialé prin aceea c nu returneaza o valoare si nut are tipul void. in al-doilea rand, functia constructor foloseste acelasi nume ca $i clasa. In cazut clasei movie, functia constructor va fi denumitd tot movie. class movie { public: void show novie(void) : movte(char *nane, char *first, char *second): private: char nano(4): char first_star{64]: char second star(s]; b Dupa cum se poate vedea, functia nu specifica o valoare de intoarcere. Ca sila functile membru ale unei clase, puteti defini functia constructor fein interiorul clasei (in line), fie in afara acesteia, Urmatorul program, CONSTRUC.CPP folo- seste funcia constructor movie pentru initjalizarea obiectelor: Functii constructor ‘include class movie { public: void show novie( vote). rovieCchar "are, char “first, cher *second): private: char nene[68); char frst_start64] char secaed star{64): wo: doe 3 Sh wie void novie::show_sovie(voia) { 2: Clase si obiecte cout << “Movie mane: * << nane << endl: cout << “Starring: “ <« first_star << * and * << second star << endl < endl 3 Deciarata functiei constructor movie::novie(char *nase, char *first_star, char *second star) strepy(novie: name, mane): strepy(novie: first_star, First_star): strepy(novie:: second star. second star) y void main(votd) movie fugitive(The Fugitive “Tomy Lee Jones”) movie sleepless("Sleepless in Seattle", “Ton Hanks”, “Meg Ryan”): “Harrison Ford fugitive. show novie( sleepless. shov_novie(): d Folosindfunciileconsructor,programele dvs, po inal obiectele a rearea tcestcra,elmindnd ale! necesatea unor full de inilalizre separate, is Cate Cor oexecthsuomat defecate data nd cea On Me obiec at une amunke clave, Funcia canstucor este spech| ald prin aceea ca foloseste acelasi nume cu al clasei. De! exemplu, pentru o clas denumita dogs, functia constructor se va numi tot dogs. In plus, functia nu returneazd nici un re-| ‘Si INTELEGEM FONCTILE CONSTRUCTOR | 0 fnecontrcer eo frie membrs a une case pe zallat sinu este de tip void. lass dogs { | public: dogs(char ‘breed, int height, int weight): — Funct constuctor | Void show_dogs(votd): | private: ‘char breed{ 64): | int height: ‘nt weight | fae Succes cu C++ ‘SA INTELEGEM FUNCTILE DESTRUCTOR Un destructor este o functie ce se execut’i automat cand obiectul este distrus. Ca sila functia constructor, functia destructor are acelasi nume cu clasa. De asemenea, functia destructor nu returneaza vreo valoare si nu este de tipul void. Programele nu pot transfera parametri la o functie destructor. Functia destruc- tor se deosebeste de cea constructor prin faptul cé este precedat de semnul tilda (-) class dogs { public: dogs(char ‘breed, int height, int weight): dogs(void): ‘vid show_dogs(vot private: char breed(64) Sint hetght: ‘nt weight: Functie destructor h Urmatorul program, DESTRUCT.CPP, adauga 0 funclie destructor Ja clasa ‘movie. Cand obiectul este distrus (in acest caz, cand programul se incheie), este apelata functia destructor: include include class novie { public void show movie(vord): ovie(char *rane, char *first, char *second): ~tovie(void) : private: char nane(64): char first_starLéd] char second_star{64]: void movie!:show sovie(votd) { cout << “Movie nane: ‘cout << “Starring: << name << endl: Movte nane: The Fugitive Starring: Harrison Ford and Tommy Lee Jones Youre nane: Sleepless in Seattle Starring: Tom Harks and Weg Ryan 1m the movie dest-uctor for Sleepless in Seattle In the movie dest-uctor for The Fugitive 59 Succes cu C++ Dupa cum observati, ul destructor, ‘Sa INTELEGEM FUNCTILE DESTRUCTOR eS Un destructor este 0 funciie ce se executi automat cand sunt scrise de functile obiectele unei anumite clase sunt distruse. Functile des- tructor au acelasi nume ca al clasei in care sunt definite, fiind precedate de semnu! tilda (-). Un destructor nu retur- neazi nici o valoare si nu este void. Programul nu poate| transmite parametri unui destructor. Urmitoarea clasé, employee, foloseste o funetie destructor: | i class exployee { public: | Pntayetchar anne, int a5): employee void) oid show eaplayee (void): private: | char nant: {int aoe: De: Functiile destructor, ca si cele constructor, trebuie si fle membri de tip publi FOLOSIREA FUNCTULOR CONSTRUCTOR MULTIPLE in Capitolul 5 veti examina suprapunerea functillor, adica folosirea unor funeti diferite, dar cu acelasi nume. in timpul compilétii, compilatorul C++ determina cce functie trebuie apelata, finand cont de numarul de parametri sau de tipul valori functiei. Cnd definiti functii constructor intr-un program, puteti specifica ‘mai multe functi, din care compilatorul va selecta funetia corecta in funcjie de necesititile programului. De exemplu, urmatorul program, MULTICON.CPP, fo- loseste doua functii constructor pentru clasa message. Primul constructor atri- buie mesajul specificat de parametru, in timp ce al doilea constructor foloseste ‘mesajul prestabilit Hello, world” #include Hinclude MULTICON ‘The message ts Hello, world The message is Success with CH FOLOSIREA ARGUM CONSTRUCTOR NTELOR PRESTABILITE LA FUNCTULE 4h Capitolul 5 vet nvata cum s& speciicay) parametri prestabliti pentru functi In cazul apelatiiunor funcii fra a specifica valor pentru fiecare parametru, se ot specifica vali prestablte, Urmétorul program DEFPARAMLCPP, foloseste ‘un pararetru pres abit pentru functia constructor a clasel message: Finclude Finclude less nessa public: soge(char *user_nessage = “Hello, world”) AY Succes cu C++ Void show message void); private: char secret _massaget64]: message: imessage(char *user_nessage) stropy(secret_nessage, user message): void message: show message(void) cout << "The message 1s ~ << secret_sessage << endl: y woid nain(votd) { sessage greeting: ‘sessage book("Success with CH"): greet ing.show_nessage(): book. show_message(): ? UN ALT MOD DE A INITIALIZA MEMBRIT UNI CLASE ‘Asa cum ai invatat, funcile constructor va ajutd 4 inilializayi membrii unei clase la crearea acesteia. La examinarea programelor C++ se poate intalni tehnica de initializare mai speciala. De exemplu, s4 presupunem ca doriti sa initilizati prin constructorul counter variabila count la 0, ca mai js: ‘counter: counter (votd) t counter = 0: 1/ Other statenents Asa cum se va dovedi, C++ permite initializarea variabilelor membru ale unei clase prin intercalarea numelui variabilei $i a valoril dorite intre simbolul *: corpul de instructiuni al functiel: counter: seounter(votd) + counter), "> Numele variable gi valoarea iniiala 11 Other statenents ee oes : i ne ‘Unmatorul program, CON_INIT.CPP foloseste acest tip de initjalizare penta alribuirea a trei variabile membru ale clasel object valorilor 1, 2 respectiv 3: 62 2: Clase si obiecte Finclude contains 1 £ b contains 2 contains 3 ATRIBUIREA VALORH UNUI OBIECT ALTUI OBIECT ‘Asa_cum intr-un program putem atribui valorile unel variabile de tip int altei Variabile de acelesi tip, similar putem atribui valorile unui object caitre alt obiect. Yeti vedea ca C++ simplificd foarte mult atribuirea de valori obiectelor. De fapt, se foloseste pur si simplu operatorul de atribuire (=). De exemplu, urmatoarea instruetiune va atibui valoarea unui obiect date altui obiect: work. day = taday: Presupunand c& obiectul date contine membrii month, day si year, operatorul de atribuire va atribui automat valori tuturor membrilor obiectului. Ca urmare, Instructiunea anterioard este echivalenta cu instructiunile urmatoare: 63 Succes cu C++ ‘work day.nonth = today.nonth: work day.day = today. da workday. year = today.year: Urmatorul program, ASSIGN.CPP, foloseste operatorul de alribuire pentru atribui obiectul movie altui obiect Hinclude ASSIGN Finclude class essage { public: rmessage(cher *user_ngssige, char owner): void show nessage (void): char nessage_ower[64]; private: 5, BAT ateen eauanon: ressage:smessageichar *user message, char *owner) € 65 Succes cu C++ ‘strepy(secret_nescage, luser_s2ss290): strepylnessage ower, owner): d void message::show_message( void) « cout << "The message owner 15." << message owner << endl; cout << "The message is " << secret message << endl y vod sane function(eessage nate) note. show message(): ? void change_ovner(nessage *rote) strepy(note-paessage omer. "Fred”): void sein(void) ssore_funct toncbook); ‘change _owner (book) sone_function( book) ) Dupé cum se observa, programul transmite obiectul book functiei some function care, la randul ei, afigeazA membrul obiectului folosind functia show _smessage. jn acest caz, funetia nu poate afiga valorile variabilelor membru deoarece secret_message nu este public. Singurul mod prin care programul poate objine acces la 0 variabilé membru este de a folosi o functie membru. Mai departe, transmiténd prin refering obiectul book funciiei change owner, functia va putea modifica membrul message owner. Ca si tnainte, functia nu poate schimba membrul searet_message deoarece acesta este private. ‘FOLOSIREA OBIECTELOR $I A FUNCTIILOR Obiectele din programe, ca $i structurile, pot fi transmise} functillor drept parametri. De exemplu, daca o functie are| nevoie s& alba acces la membri unei clase, obiectul poate fi! transferat funcjiei prin valoare. Daca functja trebuie si mo-! difice un membru al clasei, obiectul trebuie transferat functi-| ei prin referinta. SA nu uitém c& 0 functie poate.avea acces, direct ndmai la’membiii publici ai uriei clase."Péhtru a mo- | difica un membru nonpublic al clasei, functia trebuie s& fo- l loseascd o funetie membru a clase —— 66 | 2: Clase si obiecte fh Capitola 10 voli Invdja cum se tansferd clase functor, folosind referinte| te Prelimindnd astel necestatea de a aplica operator de indirectare (~») in fa nel fone in schimb, programele pot avea acces la membrii une! clase folosind operatoralpunet ().— SA INTELEGEM MEMBRU UNEI CLASE {In fiecare din programele anterioare, clasele au folosit tipuri simple de membri ‘caint, float sa.m.d Pe masurd ce clasele devin mai complexe, membril lor pot f tablour, structuri, sau chiar alte clase sau pointeri la clase. De exemplu, urma- torul program, NESTED.CPP, include un pointer la clasa date in interiorul clasel employee: Firclude Finclude class date { public: date(int month, int day, Int year): void show datetvoid): private: ‘int month; nt day: int years class employee { public fenployee(char “rane, int age, int month, int day. int year): ~enployee(void): void show_enplayee(votd) : private: char nane( 64] int age: cate *hire_date ay date::dateCint month 11 Nested class nt day, tnt year) date::nonth = month; ddate::day = day: date::year = years } void ate: : show datevotd) { cout << month << °/° << day << '/ y e year << endl: 67 Succes cu C++ enployee! employee (char *naime, int’ 868, int wonth, Jat day, ‘nt year) t stropylenployee: :nane, mane): employee: 290. age = date = new date(nonth, day. year): ‘employee: -employee(void) { delete hire date: 2 votd enployee: show enplayee(votd) cout << “Haine ‘caut << “Age: cout << “Hire date: bnire_date->show dated): } void main(void) t * exployee manager(“Joe Sxith", 33, 12, 25, 1994); “<< nase << endl << age << endl: manager. show_enplayée(): } : = z Daca nu infelegeti inca alocarea gi dealocarea memoriei din constructorul si class date { public: dateCint month, int day, int yeer): date(void) 4 ~tate(void) void show_datel void); private: 68 2: Clase gi obiecte ; ‘Gee:sdtectnt month, in dey, Amt seer © gate: month » nenth: ~date::year = years © out << “In date constructor: ‘Gate: sdate(void) cout << “In date constructor with no date” << endl datecvoid) cout << "In date destructor: show_date(: d etd date: :show date(vosd) cout << month << */" << day << “16 year << endl: 5 ; ‘oid wain(vord) Fe date holidayslEl: date christaasti2, 25, 90): date halToweenti0, 31, 94): date fouruit7, 4, 98: date new yearsit, 1. $5) date birthday(@, 30, 94) hoticayst0] = christaas: holidays(1] ~ bat Toveen: holidays(2] = fourth; holideys(3] = new years: holidays(4] « birthday: ? Dupa cum se observa, programul initalizeaza tabloul in main, Cand se folosesc tablouri de obiecte, trebule infeles c& C++ apeleaza functile constructor $i 69 Succes cu C++ destructor pentru fiecare element al tabloului. In acest caz, functile constructor si destructor afiseazi un mesaj pentru a va insliinta cd au fost apelate. La compilarea si executla programulul, pe ecran se va afiga Cake ARRAY void nain(votd) £ fofstrean alphabet (ALPHABET. DAT"): for (nt letter = "A"; letter <= 2"; Tetter#) alphabet. putt (char ietter): » jin acest caz, programul foloseste functia membru put pentru a scrie valori de: tipul int sub forma ASC Urmatorul program, ABC_INS.CPP, realizeaz4 o procesare identicd, scriind caractere in fisier cu operatorul de inserte. finelude include pid main(void) ‘fstream report “EMPLOYEE. RPT"): & struct [= char naneteay: = int age: char ssanf64): Aloat salary; ae Yemployeest) = {{-Robert Jones". §1, "11-22-3333", $5000.00). ‘(Betty Smith”, “43, '~333-22-1111", 60000.00), : ‘(Reggie ATlen*, 30,,"111-11-0000", 9900.00)};, report <= “Home\t\tage\tSSAN\e\esaTary” << endl: © for Cint i= 0: 1 <3 ty = ( : IE report < setanfiagatis: -employees[i]..nane:; * report LOGFILE Formulate budget proposal” C:\> LOGFILE Start research for new CD-ROM product. In interioru fsierului LOGFILE DAT, intrtile vor ardta astlel C:\e TYPE LOGFILE, OAT 11/09/93 17:07:38 Formulate budget proposal 11/09/93 17:07:50 Start research for new CO-ROM project Urmatorul program implementeaza LOGFILE.CPP: Finclude void main(int argc, char *argv) ‘ saan ee nee ofstream output_fiTe(*LOGFILE.OAT", fos: :epp) char timet9]. date 9] 3: Fisierele arse > D ‘utput_file <_strdate(date) << * * << _strtine(tine): wnvte (sara { output file Hoclode * FSTREAMH. Aj Josind functia membru close. Urratorul ppasli ce trebuie urmati pentruca citi date include Inclde orl entot FSTREAM void maintvotd) C char text{2s6): ‘DESCHIDEREA UNUI FISIER PENTRU INTRARE Pentru a ctl informatii dintzsun fisier, programul trebule 4 Creeze un obiect de tipul ifseam, defini in fisierul antel i, figienul trebule deschis prin functia mem- bru open sau prin funcia constructor. In continua, Progra: ‘ul poate folesi operatorul de extractie pentru a citi date din fisier, Dupa terminarea prelucrai, fisierul teu pagina, trebuie ape inchis fo- 1 program ilustreaza dinte-un fisier: 84 Succes cu C++ 8 in blac da Tareas ‘reas budiet /amserDAN") + Oeste ud Exccut ces budget.ctoset: 1: chide fer i i budget.getlinectext, sizeof(text)): TESTAREA REUSITEI UNE OPERATII I/O. Doua din programele anterioare au folosit functia membru fail pentru a determi- na daca programul a putut deschide cu succes un fisier pentru intrare, cum se arald mai jos ‘fstream input (arava): if Ginput. fai) ‘cerr << “Error opening the file: * << argv{l] < endl: Asa cum afi invatat la Capitolul 1, functia membru fail returneaza valoarea 1 daca a avut loc 0 eroate la ultima operatie pe fisier. In acest caz, programul a detectat mumai erorile la deschiderea fisierulul. in Capitolul 1 ati invatat totus A trebuie sa testatireusita flecarei operatii de citire sau scriere. Urmatorul pro- gram, ASCICOPY.CPP, citeste continutul primuluifigier specificat in linia de co- manda, copiind continutul acestuia in al dolla fisier al liniei de comanda. include Votd mainGint argc, char **argv) ‘fstream sourcetargvtt]): cher Vine( 128): if (source. 9410) egitr” “ETOr opening the file: ~ <= arevEt} Fincluce oid nain(void) Moat price: sfstream stocks("STOCKS.OAT”, fos: :binary): while CL stocks.eof0) stocks,reae( (char *) Bprice, sizeof(float)): cout <¢ setprecision(2) << setiosflags(ios::shorpoint | fos. sfixed) << price <© endl. } stocks close) y Dupa cum se vece, programul cicleazé, citind valo Intalnirea marcajului de starsit de fister. - y ia continutul unui [Aji ereat mai devreme programul ASCICOPY.CPP, care copia continuls} Wirt fsier ASCIT in alt fiser. Urmdtorul program, BIN_COPY.CPP, deschide Tisiere sursd ) destinalie in mod binar, cea ce permite programului $4 cop! fisiere text, cat si Tsiere binare: rite reale din fisier, pana la oe 87 Succes cu C++ include void main(int arge. char *arge) { ifstrean source(argv{1). tes::binary): char Vine( 1): Af (source, fai100) ‘corr <= “Error opening the file: * << argv{t) << endl: else ofstream target(argv[2], 10s::binary): af (target. f210) err << “Error opening the file: else << argut2] << endl: while Cl souree.eof() && 1 souree.fai1(0) { source.reed(Vine, sizeof(Vine)) Af (source. good) target.wette(Tine, sizeof(ine)) if (target f2110) { err << “Error writing the file: * << argy{2] << end: exit); y else sf (1 source.eof() err > value: cout > values cout > value: cout << value © should be "<< 100.0 / 11.1 << endl: jd nain( void) ae ofstrean output("BAD_OATA.OAT", tos: :binary): hnideftoat values value.data = 100.0 / 31.2: ‘nput.close(): natput << vaTLe: y La compilarea si executla acestui program, pe ecran vor apérea rezultate similare cu urmatoarele: value.data = 22.0 (7.05 output << value value.data = :00.0/ 11-2: output << value: rN BAD_IN. “ 9.009001 stoulé be 9.009001 f 0.142869 should be 3.14286 : : (0,00901 should be 9.009001 Noe close: be fecare data cénd complatorul C++ Intneste 0 valoare de ine) hidefloat oe cares operatorul de inser si cu un seam figier de lest, Progen aa funciia operator ce foloseste, la randul ei, Functia membna wile pentru a ‘erie valoarea bnard in figie. Pentru citirea unl figier binar, se poate folor ardtat mai jos! Dupa cum se observa, valorilecitite din figier nu corespund valorilor scrise initial fn figler, $1 iat de ce. In mod prestabilt, cAnd programele efectueaza iesiri pe flux, funetile stream-ului de lesire convertese valorile de diferite tipuri in re- prezentari ASCII. De aceea, dac& am dori s& vizualizsm continutul fisierulul BAD_DATADAT folosind comanda TYPE, pe ecran ar aparea: ‘mnitorul program, READ BIN.CPP, Cele TYPE BAD_OATA. 9 ons00%0.2eé, 006002 include anton aes boon —— struct hidefloat { float data: }: Cénd un program va eit! mal triu alone din acest filer, el va tncerea si Canerleasen caracterele ASCH in valor eal. Din eferce, aga cum sa Vaz Seneca progamutuc aceasta conversie nus realizeazi creel : Daca totus! dors folas operator de insenfefetacte cu fire binare eee dortbane acest operator pentru a folsfunctile read s} rite Ueetige antuson Din pce, Cr+ va permite suprapunerea operatonilor de ‘teatjeretacje numa pentatipoi de date nol, deftein program. Urratora sfstreant operator >>(ifstrean file, hidefloat *vaTue) peor 9 waa, stenf(080% ents: y void main(void Succes cu C++ { ‘fstream input ("BAD_OATA.DAT", ios::binary? hideftoat value: input >> value} cout << value.data << * {input >> valve: cout << value. data << * ‘input >> valve: cout << value.data << ~ should be should be * << 100.0 / 11.1 << endl: should be * << 22.0 / 7.0 <« end) * << 100.0 / 11.1 #include ASCTAPPD. TOOAY.NTS WEEKLY.NTS Tot in acest capitol, afi creat mai tnaintefigeral ASCICOPY.CPP care copiaz8 confinutul unul fier ASCII in alt fgier. Dacd al doilea gler exlsta deja, programl va suprascrie continutul Hsierului existent. In alte situa nu este fecomandabilé 0 estel de suprascrcre (deci o dsirugere) a figierelor, Pentru a preveni suprascrierea fisierelor, se poate folosi speciicatoral de mod de dleschiderefos:noreplace, cum se araté mai Jos: efstrean output e(“FILENAME.EXT", 05: :noreplace) 95 Succes cu C++ Urmatorul program, OVERWRIT.CPP, foloseste specificatorul ios:noreplace pentru a preveni distrugerea unui isier print-o operatie de copiere. include void main(int arge. char *argv) Afstream source(argv(1],. 1os::binary): ‘chor Vine(13 Af (source. a¥10) cerr << “Error opening the file: else ¢ ofstrean torget(argv(2]. * << argv{] << endl: soss:binary | ios::noreplace): Af (target-ta110) carr << “Error opening the file: “or file exists” << end << argv2) « else vite (1 source.eof() Ab t souree. fa11(9) source.read(Tine, sizeof(Ti9@)) 4 (source. good() targot.write(Vine, sizeof(1ine)) if (target fai) { cerr << “Error writing the file: argv{2] <= endl exit): y d else $f (1 source.cof()) « cerr <« “Error reading the file: argv(2] << endl: exit(a) y y source.close(): target closet) ; eae eye ee . y d 96 3: Fisierele "upd cum se obser, dacd filer destinatle exist, programul va affga un mesaj de eroare si se va incheia. Programul poate fi modificat de asa natura Incat s& intrebe utlizatorul daed un fisier existent poate sau nu sA fie suprascrs, ‘Si INTELEGEAI FISMERELE CU ACCES ALEATOR | 1 | Majoritatea programelor realizeazatintdr/iesitisecventiae, preluctand fiserele de la inceput spre sfarsi. Operatilepe| fsiere cu acces aleator, pede ata parte, permit programelor| si efectueze citi sau scien! de pe orice locate a fiserulul Inainte de a incepe operatile, programul poziioneaza poin-| tel de fisier pe locatia dorita folosind functile: membra |scekp siseekg, Functia seekg poctioneaza pointerul de intrare (ge) a fsierulu in timp ce funcyja seekp poztioneazé pointerul de iesire (put) al figierului, Am- ble fact specticslocala de positional folosind un deplasament fat deine: | putul, sfrsitul sas poalia cutenté a fisierului. Dupa pozitionarea pointerului de fis rn funcile membru read sau write. | REALIZAREA IFSIRII LA IMPRIMANTA Exist situatii cand iesirea trebuie efectuata nu pe fisiere, ci la imprimanta. in general, imprimanta poate i tratata ca un figier de iesire care va fi deschis cu numele de disporitiv PRN. ofstreanprinter("PaN") De exemplu, programul PRTFILE.CPP tipareste la imprimanta continut figers- Iui specificat de primul argument al liniei de comanda: Hinc1ude™ void mainCint argz, char *argv) char text(286): ofstream printer (*FRN"); Hfstrean fite(argvt)): if efile. fo4109 ccerr << "Error opening the file * << argv{1) << endl: else while (1 file.eof() ‘Hie. getline(text, stzeof¢text)): if (f¥@.g00d(0) 97 \ Succes cu C++ Fisierele sa< ; TEL] formate pe sire De aserenea, se po see pe ire printer <¢ text < endl; 2g g| custo specilecala,\ auchiarn ee al 22 & | La deschiderea ums ger peta inrare sau ese, { ; 39] programete pot folosi specificatorii modului de deschidere cere include class spotted dost { abies potted doas(char *breed. int height. int weight, char ¥eolor, char *spot_cator) veld show breed(oi@s x + noes void spot infoCvoid): private char Breede}: 102 } 4: Mostenirea claselor int height; ‘nt weights char color[68): char spot_colort64]: class unspatted dogs { public: Uunspatted_dogs(char *breed. int height, int wetsht, char *oter void show breed(void): private: y spotted dogs: t y void spotted do } void spotted do € 3 char breest6a): int height: ‘nt wetght char cotort641: petted dogs(char *breed, int height, int wetght, char *color, char *spot_color) strepy(spottec_dogs: breed, breed): spotted, cogs: height = height: spotted dogs: weight = weight: strepy(Spotted dogs: :color, color): strepy(spottec_dogs::sp0t_color, spot_color): show_breed(void) cout << “Breed: " << breed << endl: ‘cout << “Height: ~ Breed: Dateatian Height: 24 Weight: 60 : Color: white et Spot color:black or brown (1iver). Datnatian has black or brown (iver). spots Breed: Labrador Retriever Wetght: 24 Wetght: 65 Color: black or yellow Daca priviti cu atentie cele dou clase, veti observa ca ele contin cétiva membri ‘comuni, Folosind conceptul de mostenire, se poate crea o clas ce contine membrii comuni, apoi alte doua clase mai mici ce contin membrii specifici pentru cainii cu pete si fara pete. Sa credm, pentru inceput, clasa dogs ce Ccontine membrii comuni: class dogs ¢ public: . as eye does(char *breed, int helsht nt wetght, char *coTor): void show_breed( void): privat 104 4: Mostenirea claselor char breedt64]: {nt hesght: ‘nt weight: char coTor{6A): } SS creém acum dou clase mai mici bazate pe clasa dogs. Cu alte cuvinte, doud clase care mostenesc caracteristcile (memibril) clasei dogs. Urmatoarele ins- tructiuni, de exemplu, creeaza clasele folosind mostenirea: class spotted does public: spotted_dogs(char *oreed, int height. int weight, char ‘color. ‘char #5pot_color); vod show treed(void); void spot infavotd): private: cher spot_color 64]: public dogs { y class unspotted dogs : public dogs { public: unspotted dogs(char “breed, int height, int weight, char color), ¥ Observati semnul ":" situat dupa numele claset si urmat de cuvintele public dogs. Semnul *:” informeaza compilatorul C++ cd clasa definita mosteneste caracteristicile clasei care urmeazi ash cera : Toss spotted dias + publle dogs { pate doe Cash de boxe Dupa cum se observa, clasa spotted dogs adauga noi tunel membru $1 0 Vvanabilé membru. Clasa unspotted_dogs nu adauga nici un membra nou, deoarece caini fara pete nu au nevole de alte caracteristci, in afara celor lumizate de clasa de bazé dogs. Programul ar i putut folosi, pur si simplu, clasa dogs, la fiecate create a unui obiect de tipul caine fara pete. Totusi, pentru imbunatatirea claritatii programului (pentru a permite programului sa Iucreze cu caini cu pete si cain’ fara pete, in loc de cain cu pete si caini), s-a derivat clasa unspotted dogs. 105 LEGEM MO$TENIREA CLASELOR Cand se definese clase Intr-un program, apar situaii cind dou sau mai multe clase au caracterstct comune (aceiasi memibri) in loc de a reproduce membrii in fecare clasé, se poate defini 0 clasdé de bazd ce confine functile membru Comune. Apoi, se pot construi (deriva) clase succesive din clasa de bazi. in acest caz, clasele derivate mostenese caracteristicile claset de baza. Sa presupunem, de exempiu, A definiti urmatoarea clasa vehicle: class vehicle { | poblie: vehicle(cher nane, int wheels, int engine): void show vehicle(void): private: | char rametse): int wheels: int engine: | | Folosind mostenirea, se poate deciara o clas motorcycle astfel: class notorcycte publi: |” sotoreycle(char *nane, int wheels, int engine, int seats): void show cycle(void ‘nt seats: public vehicte { |: |in acelasi mod, se poate dectara gi clasa automobile: class automobile: public vel [oat ier | Putonoe(char tran, tot wheels, tnt engine, int doors) te { void show_auto(votd) private: int doors: b In acest caz, clasele motorcycle si automobile mostenese améndous caracters- ticle definite in clasa vehicle. 4: Mostenirea claselor _ FOLOSIREA FUNCTIILOR CONSTRUCTOR LA MOSTENIREA CLASELOR ‘Asa cum ati invatat in Capitolul 2, functile constructor permit programelor sa jniializeze variabilele membru ale claselor. Tot constructorii se folosesc pentru inializari si In cazul mosteniriiclaselor. Singura diferent este aceea ci, con- structorul clasei derivate trebule s& apeleze constructorul clasei de baz. Urma- toarea functie imp ementeaza funclia constructor a clasei de baz dogs: dogs: :dogs(char *breed, int hetght, int weight, char color) { stropy(dogs: :breed, breed) shefght = hetaht weight = weight color, color): Functille construccor ale claselor derivate folosesc o sintaxa similara defintiei casei, avand simbolul":" urmat de functia constructor a clasei de baz’: Constructor clas devata ‘Spotted dogs::spotted dogs(char *breed, int height, int weight. char "color, car *spot color) : dogs (breed, height. weight, color) “constructor 2as8 de axa strepy(spotted dogs::spat calor, spot color): imépotted dogs: :urspotted dogs(char:vbreed, ‘int height, int weight, Char, tcolor) « dogs(breed, height, weight. color) 7/09 nothing-basé class constructor initialized menbers. +’ y ‘Asa cum se poate vedea, apelul constructorului clasei de baza foloseste nume de parametti idervici celor transferati constructorului clasei derivate. Pramatri clei dorvate spotted donated, dogs(ehar “FEES, THE PETGHE, THE WeTGTE, Ghar "color, cFar *spot color) : dogs (breed. height, weight. color) ( \—__arareti case de baza strepy(spotted dogs::spot color, spot color) Uunspotted dogs: :urspotted dogs(char *breed, int height. int weight char *eolor) : dogs(breed, height, weight, color) 11 09 nothing-base class constructor initial zed menbers 107 Succes cu C++ ‘Cand programul apeleazd constructorul clasei spotted dogs, C++ va apela aw tomat, mai intai, canstructorul clasei dogs. Functia constructor a clasei de baz’, este intotdeauna apelat inaintea constructorului clasel derivate. in acest mod, membrii clasei de baz sunt corect initalizai, iar memoria va fi corect alocal’, pentru butfer-ele clasei de baza, inainte de referinea clasei derivate. Dacai examinat} functia constructor a clasel spotted_dogs, veti vedea ci initial zeaza variabila membru spot_color. in schimb, constructorul unspotted dogs nu are valori de atribuit (in afara celor folosite de constructorul clasei de baz). Urmatorul program, NEW_DOGS.CPP foloseste mostenitea pentru a crea clase. Te de caini cu pete gt fara pete. include class dogs { public: ogsichar *breed. int height, int weight, char *color): void show breed(ioia): private: char breed(64): int height: int weight: char color[64): ¥ class spotted dogs : public dogs ( public: spotted dogs(char *breed, int height. int weight, char *cotor ‘char’ *spot_color) void, show bread(void): veld spot_infocveid) private: char spot_color(64] ¥ class unspotted dogs + public dogs { public: unspotted dogs(char “breed, int height, int wetght. char *color): ¥ gs: :ogs(char *breed, int height. int weight, char *color) { : strepy(dogs: breed, breed) + < dags:shetgnt: = hevghts* > ‘dogs: weight = weight: strepy(degs: :coler. color) 108 Mostenirea claselor jtted_dogs::spotted dogs(cher ‘breed, int height. int weight, Pchar *calor, car #spot.color) : dogs (breed, height. weight, color) © strepy(spotted.dogs:spot_color, spot color): " unspotted.dogs: :unspotted_dogs(char *breed, int height, int weight. U char *color) + dogs(breed. height. weight, color) { (1100 noting-pase class constructor ‘nitattzed nxbers =} void dogs show breedvo%0) af OE aut << “breed << breed << endl: Shut << "Heights" << hetght <= Weight: * << weight << endl: fut << “talon ~ ce color < endl } ‘void spotted dogs :show breed(votd) dogs: show breed(): cout <<. "Spot color: *<« spot color << end) << endl; } void spotted dogs: :spot_infotvoid) ‘cout << “This breed has ~ << spot color <<" spots” << endl << endl: } ‘ , void maincvoid) € spotted.dogs happy("Dalmatian”, 24, 60. “white”, “black or brown (Tiver)"): unspotted docs rover("Labrador Retriever”, 24, 65, _ "black or yalTow"): happy. show breed) happy. spot_inf(): rover show_bresd(): ? Deoarece clasa spotted_dogs conline membrul spot_color, casa foloseste func {ia membru shot breed proprie. Folosind operatorul de rezolutie global& (=) unclia apeleaza mai intai functia show breed a clasei de bazd pentru a afisa variabilele memtru comune tututor raselor de céini. Apoi, functia aflgeazé va- loarea propriet variabile membru: 109 Succes cu C++ void spotted dogs: show breed(void) Apelatea func clase de axe € oo ogs::show breed: _—— Atgares varia! emt ot coor cout <« "Spot color: * << Spat Color << endl <= endl } La compilarea si executia acestui program, pe ecran va apirea: C\> NEW DOGS. Breed: Dalmatian Height: 24 Weight: 60 Color: white Spot color: black or brown (Tiver) « ‘This breed has black or Brown (Iiver) spots Breed: Labrador Retriever Height: 24 Weight: 65 olor: black or yellow ‘84 observ ca in lesirea programuluis-a schimbat urmatoarea Inte: Datmatian has black or brovn (Iver) spats ‘ais breed has black or brow (Iiver) spots Programulfoloseste functia spor_info pentru a afiga mesajul corespunzator: Soh epttd dene :epe. notte) cout << “This breed has endl y In acest caz, functia nu poate folosi variabila breed a clasel dogs, care contine humele rasei (Dalmatian), deoarece aceasta nu este publica in clasa dogs. ‘Singurul mod prin care o clas derivat’ poate avea acces la membrii privat clasei de bazd este de a folosi functile membru ale clasei de baz, cum este show breed. Un alt mod de a rezolva aceasta problema este de a face variabila membru breed publicd in clasa dogs. De asemenea, aga cum veti vedea mai térziu, se poate declara variabila ca find un membru protejat (protected) a clasei, cea ce va permite accesul direct numai prin intermediul obiectelor claset derivate sau ale clasei de baza. << spot. color << * spots” << endl << ANALIZA UNUI EXEMPLU Pentru a injelege mai bine cum si cénd sunt apelate functile constructor si destructor In situatia mosteniti claselor, urmatorul program, GENERIC.CPP, defineste doua clase, denumite base si derived. In cadrul fiecgrui constructor * sau destructor, progiamul sfiséazi-un mésaj ce identificé functia"cufenta: #include include 110 Set 4: Mostenirea elaselor yass base ( Me base(char *base_messose) Shasetvot: ‘ate: Poparbase_nesseooC 68): ‘class corived : public base { public: derived(cher *éerived message): ~terived(void) private: ‘char derived message( 64] se: rbase(char message) agen strepy(base_message, message): cout << “In bas? class constructor; * << message << endl } bese: -base(vord) cout << “In base class destructor: " << base message << endl: y Gerived::derived(char *nessage) : bese(‘Hello, base") strepy(derived message, messege): cout << “In derived class constructor } ertved: + ce nessage << endl; y” derived(votd) cout << “In derived class destructor: * << derived message << endl } void main(void) Gerived object! "Hello, world"): , La compilarea si executla acestui program, pe ecran va apirea: C:\> GENERIC tela, urmat de simbolul *:" si de numele clasei de baza, ca = int. sectors per track: int bytes per sector: “ore capacity: class derived : public base { Nee ‘poi, programul deriveaza clasele harddisk si loppy_ disk, ca mat jos: _Dupa cum se obser, defnitiaclasel derivate foloseste cuvdntl-chee pubic, | Aceasta inseamna cé membri de tip public ai clasel de baza sunt considerali |e acelas tip sh in clasa deriata In acelag! mod, mernbr proj (rofec, ted) ai clase de bazd sunt tratali ca membrl proteja in clasa derivata, Major ‘tatea programelor vor folosi cuvantul-cheie public ca mai sus, Dacé la def| [nia unet clase se fooseste cuvantul-chele private, atunc! membii publi si |proteati ai clasei de baza vor fi tratayi drept membri nonpublic (private |clasa derivata Glass floppy. disk’: public disk ¢ public: floppy disk(cher *nane, int sides. int tracks, | $n sectors per track, int bytes per sector. int state): void set write protectCint state): ‘void show floppy void): © private: int write protect. state; i ‘lass bard disk + public disk { = public: ‘hard disk(char *nane, int sides, int tracks, ‘ng sectors. per. track, int bytes per_sector. | char controler type): void show hard disk(vo%d) 4 private: f char controle typel4): ANALIZA ALTUL EXEMPLU nd va sini la unitate de dsc, asocii intotdeauna anumite attbate, precum: capacitatea de memorare, geometria discului (numarul de fete, piste, Eectonre ete), sar vtera de transfer, Aga cum se ara In Figura 41, aceste caracterisicl sunt mostenite atét de hard-dsk-uri cét si de dlschete, fecare dintee ele ava si caractersc propri, ca tpul Ge nterfata (SCSI sau IDE) sau ‘mecanisimul de protect lascriere Programul DISKCLAS.CPP este redat in intregime in conlinuare: Hinclude Hinclude DISKCLAS Disk mame: Hard disk Sides: 4 Tracks: 615 Sectors per track: 80 ytes per sector: 512 Capacity: 100763600 bytes Controlter type: IDE Disk nase: Floppy disk Sides: 2 Tracks: 8 Sectors per track: 18 Bytes per sector: 512 Capacity: 1474560 oytes Wite-protect is: Jn 15 Succes cu C+ UN ULTIM EXEMPLU DE MOSTENIRE PE UN SINGUR NIVEL Probabil cd deja v-ati obignuit cu sintaxa claselor de baz gi a celor derivate. Sintaxa reprezinta “sliinta" programaril orien’ate pe obiecte. “Arta” acestel programa incepe cand (rebuie s& determindm care din atribute apartin clase- Tor de baza, si care atribute trebuie sé figureze in clasele derivate, Cea mai bund metoda de a stapani “arta” proiectirii orientate pe obiect este de a exers permanenta, de a rafina treptat conceptele introduse. Sa analizém din nou un exemplu, $4 presupunem ca trebuie sa creati o baza de date a angajatilor unet mari companii, Compania are manageri cu salariu anual, angajati permanent) platiti cu ora, si angajati temporari platiti cu ora. Pentru fiecare tip de angajat, programul trebuie sa urmareascé urmatoarele informatt: s Permanent ex o “Temporar cu ora telefon acas telefon cast telefon aeasa telefon servic telefon seria telefon servic solos anual psa peor plata pe ors Donic superior irae superiorierarbic superior irarhle asitent Prima “miscare” care se face la proiectarea clasei de baz’ este de a selecta atribulele comune, ca mai jos: ‘Stari Permanent ew ora__Temporari eu ora telefon acest telefon acas telefon aca telefon seni tolfon sane telefon serch salariu wal plata pe ort plata pe ort bonieas superiorierarhic —_supetior varie superior erable salstont eto Folosind alsibutele comune, se poate acum crea clasa de baz employee, cum se gratdi mai fos’ class enployee ( public: feeployee(char *nane, char *hone_phone, char ¥office_phone, 116 : Mostenirea claselor char ‘reports_to) [void show_esplayee(votd) | private: char namel64] char home_phoret64); cher office pronot6a] char reports tol64]; Apol, nlaturdnd aibutele comune, clasele derivate devin: class salaried : public eaployee { pblics salaried(cher *mane, char *hote phone, char toftice phone, char reports to, float salary, flost borus, level char *assistant) void show salarted(votd) private ‘lost salary: ‘leat bonus level: char assistant{6d}; ¥ class hourly : public employee { public: hourly(char Ynane, cher hone phone, char toffice phone, char *roports to, float waze) votd show, hourly(void): private: Float wage lass temporary : ubLic employee { public: ‘temporery(char *nane, char *houe phone, char *office phone, char *reports_to. float wage): void show tenporary(votd) : private: Float wage Daca examinati clasele hourly si temporary, veti vedea c& membril lor sunt dente, Tocmal ak ara preferintele programatontl sal asemenea faciod intra in rol In funciie de modut in care programul lucreazs cu oblectele, se poate crea variabilé membru‘n clasa hourly cu rol de indicator, pentru a preciza daca un obiect corespunde unui angajat permanent sau temporar, ca mal jos fxn worker. type { peenanent, te onary } ‘lass hourly + pubtic employee { a WW 4: Mostenirea claselor Succes cu C++ public: ‘tenporary(char *nase, char *hove_phone, char *office_phone, ‘char *reports_to, float wage, worker type f12q): void show_tenporary(void); private: Moat wage: worker type flag char reports :0(64 class salaried : public employee { public: salariedichar *nane, char *howe_phone, char *office_phone, char *reports to, float salary, float bonus level. char *asststant): o void show salaried(void) private: float salary: Float bonus_level; char assistan: (68); x fn cadrul functillor membru ale clasei, codul acestora trebule s& examineze va- riabila indicator pentru a determina tipul corect, Exist unele situatii in care se doreste restrangerea anumitor operatii din pro- ‘gram la angajatli temporari sau permanenti In astfel de situatii obiectele tip an- ‘ajat nu mai sunt aceleasl, lar programul trebuie sd foloseasca doua tipur dis- lincte de clase. In acest fel, clartatea programulul se va imbunatati. De exem- plu, urmatoarele fragmente llustreaza o functie care limiteaz opera supra angajatilor temporari cu ora class hourly : public employee { atic hourly(char *rane, char theme phone, char *ottice_phone. char *reports to, float wad void show hourlyGvoia): private oat wage Float temporery::pay.overtine(void) float hourly::pay_overtineCvotd) { 11 Statements $f (tag = temorery) 1 Statesents ? 4 class tenporary : public exployee { : public: ‘temporary(char *nane, char *hose phone, char *office_phone, char *reports:to, float wae void show tenporary(votd): private: : float wage: y Prin simpla examinare a antetului {_..\iei pay-overtime din partea stangé, persoand care citeste programul poate imediat sé determine c& functia se aph ‘cd numai obiectelor de tip angajat temporar. In cazul functiei din partea dreap- 1, cititorul programului trebuie s& alba acces la instruetiunile sursa (in parti- cular, instructiunea if) penta a afla c& functia afecteaza numai obiectele de tip permanent. Urmatorul program, WORKERS.CPP, foloseste clasele employee, salaried, per- ‘manent si temporary: exployee: employee(char *nane, char *hone phone, char *oftice_phone, char *reports_to) { strepylenployee: :nane, nana): strepy(enployee: :hose phone, home phone): strepylenployee::office phone, office_phane) stropy(enployee: :reports to, reports to): Finclude Hinclude class exployee { public enployee(cher *nane, cher *hone_phore. char *oftice_phone. char *reports_to) void show_enptoyee(void): private: ee z os ‘char nane[6¢]: char hone_phone( 64]: cchar of F1¢e_ phone 64]; void employee: :show_empoyee(void) cout << "Wane: * << nane << endl cout << “Hone phone: “<< hoe phone << endl: cout <« “OFFice phone: * << office phone << endl: cout << “Reports to: ~ << reports to << endl: ) 118 119 120 Succes cu C++ ‘salaried: salaried(char *nane, char *hore phone, char *office phone, char reports t0, float salary, flost bonus level char assistant) : employeo(nane, hone phone. office phone, reports to) { salaried::salary = salary: salaried: :bonus level = bonus level: strepy(salariedi-assistent, agsistant) } Void salaried: show salaried(vord) { show. emptoyee() cout top boss. shor saered(): cut << endl «endl: typist. show. hourly): cout << endl << endl; receptionist ston_tenporary(): La compilarea si execulia acestui program, pe ecran vor aparea urmatoarele rezultate: CaN WORKERS Nane: Joe Sith Hone phone: 555-1111 Office phone: §55.1112 Reports to: Mark Jones salary: 530000 Bonus level: $10020 Assistant: Alicia Jones Name: David K142 Hore phone: 555+ Office phone: §55-2223, Reports to: Jon vartin Wage: $4.5 ane: Mary Scott ‘ Hone phone: 555-3393, ‘Office phone: 555.3334 Reports to: ors Davis wage: $4 Tr ‘PROTOTIPURI, REVIZIL, FINALIZART ES I Programarea orientaté pe obiecte este att ana, cit si stinl. > © upd ce aff seris primele programe, stinta prograrnarii ori entate pe obiecte devine destul de clara, Aria proiectati programelor consta in atribulrea corect& a membrilor catre Clasele de baz’ sau derivate, De regula, se considera prima clasa proiectata si membrii ei Jdrept un prototip. Pe masuta ce dezvoltall programul, revedeti si actualizall membrii claselot. In majoritatea cazurilor, aceasta duce la eliminarea rescrietit [codulul intr-o etapé ullerioara, cauzata de o proiectare initiala incorecta. 121° Succes cu C++ in general dacd of giaij iv stuns de a Wansmite paramett unor Fanci ce | contin ormati supimentare despre un oblect,atunch ebule 8 refaceli oa |proiectarea, Daci in schimb extindeli codul, atunci ramane 0 usa deschisé [ents err arclartatea programut ve ven de suf | SA INTELEGEM MO$TENIREA MULTIPLA Exista situalfi in care unele clase folosese caracteristicile a doud sau a mai ‘multor clase de baz, Mostenirea multipli este folosirea a dou sau mai multor clase de baza pentru derivarea altel clase. S4 presupunem, de exemplu, c& sau declarat clasele book gi disk: class book ( patie: ‘book(char *title, char ‘author, int pages): void show_book(void) private: char titte(s4]: char euthor[64) ‘nt pages: » class disk ( public: ‘disk(Float capecity): void show disk( void); private: float capacity: ¥ class bundle public: bundle(char *title, char *author, int pages. float capacity, float price): void show_bundle(votd): private: Float price: a Se poate apoi crea o clas denumita bundle care este o combinatie intre cele doua clase anterioare: public book, public disk { class bundle public: anne: bindle(char *titte, Shar” *éathor float price): void show_bundle(void) public book, public disk { ‘nt pages, float capacity,” 122 4: Mostenirea claselor © private 7° float price: y Inacest caz, bundle este clasa derivata, iar disk $i book sunt clasele de baza: cast deats class Bundle : public book, public disk { ‘case de bess Cand o clasé este derivaté din doua sau mai multe clase, clasele de la baz se separa prin virgule, cum s-a ardtat mai sus. La declararea functiei constructor al casei, rebuie specificat constructorul clasei de baza intr-un mod similar: Construct class derivat pindle;sbundie(cher *title, char *author int pages, float capacity. Float price) + book(title,. author, pages) , disk(capacity) bundle: :price = prt y In acest caz, C++ va apela mai intai constructorul book, urmat de functia disk sitn final de functia bundle, Urmitorul progrem, MULT_INH.CPP, ilustreaz4 mostenirea _multipla prin crearea clasei bundle. Programul nu face altceva decat s4 apeleze functille constructor si destructor, care la réndul for afigeaz8 mesaje pentru urmatirea executie Constucor aes de baza include MULTLINA ln acest caz, cénd programul va apela constructor clasel derived, C++ va apela mai ina consiructonul casei basel, apol constructor clasel base? SA INTELEGEM MOSTENIREA PE MAI MULTE NIVELE ‘Asa cum am vézu,, mostemirea mulipli const in folosirea a dows sau mai mul- tor clase la baza pentru a deriva 0 noua clas, Mostentrea pe mai multe nivele, pe de alti parte, ae loc la derivarea unel clase dint-o clasa de baza care, la ran- dul ei, este derivaté din alti ciasa. De exemplu, Figura 42 ilustreaza clasa mana- Ber, bazald pe clasa worker, 2ceasta find la rardul ei bazata pe clasa person. Penta crea cele 3 clase, Incepem cu clasa person, ca mai jos 125 Succes cu C++ class person { public: person(char *name, int age): vvotd show person(void): private: ‘char nane(64): ‘nt age: Manager Figura 4.2. O mostenire pe nivele multiple Apoi, definim clasa worker astfe: class worker : public person { public worker(char Amane, int age, char *phore, float wage): void show worker (void) : private: char phone( 64): float wage In sfrsit, vom defini clasa manager: class manager: public worker { public: mmanager(cher *nane, int age, char “phone, float wage. char *of fice): void show manager(votd); private: char offtce(6¢]: h Urmatorul program, MULTILVL.CPP ilustreazé mostenirea pe nivele multiple: sHinclude MULTILVL Nene: Ken Smith Age: 43 Phone: §55-1232 ene Nene: Betty Louts Age: 30 Phone: 85-2121 office: Reon 38 SA INTELEGEM MEMBRI DE TIP PROTECTED AI UNEI CLASE ‘Aga cum at{ invatat in Capitotul 2, functile membra ale clasei se pot deciara de tip public saw private. La declararea unui membru ca public, acesta va 1 accesibil in tot programul (cdind abiectul este in domeniu - vezi Capitolul 9). Un membru de tipul private poate fi accesibil numai prin funciile membru ale clase in programele din acest capitol, clasele derivate au avut acces numai la membrli de tip public ai clasei de baza. De exemplu, urmatorul program, INPUBLIC.CPP, ilustreaz modul in care o clasd derivatd poate avea acces la membiil de tip public ai clasei de baza. In acest caz, programul are acces la membrul de tip public base number al clasei de bazé, dar nu are acces la + membrul nonpublicbasee message: . 128 Binclude Finclude » 4: Mostenirea claselor ‘lass base { F pubtic: ©" base(char *base message, int nunber} int base_runber: | private: char base_sessae(64] class derived : public base { public: derived(char *éertved_nessace private: char derived nessage(64]: } base: :base(char *nessaee, { strepy(base_nessage, ressage) base_rurber = number: } derived: sderivedtchar *zessage. int nurber) : base("Base message ‘unber) {int number): ‘nt number) strepy(derived nessage. message): } void main(votd) derived object!"He} 0, world", 2001 ) cout << “The base munber 1s “ INPUBLIC Eira The base munber 15 1001 Exersafi cu acest program astfel incat functia main sa faca refering fa variabila membru base_message, in loc de base_number. Deoarece membrii nonpublict fu sunt accesibil. in alara clasei, nici Obieciele derivate nu vor avea. acces la acestia, In funetie de intentia programulul, pot aparea situalli cind se doreste ca unii memibri ai clasei de bazi si poatd fi referiti de obiectele clasei derivate, flind tolUsi protejati de restul programului, In aceste cazuri se pot folosi in program ‘memibri protejati, Un membtu protejat (protected) al unei clase poate fi direct folosit de clasele derivate, dar nu si de alte parti ale programului. Urmatorul program, PROTECT.CPP, ilusireaza folosirea membtilor protejati ai unei clase: 129 Succes cu C++ include Finelude class base { public: base(char “base sessage, int number): protected: 4ntbase-nunber: private: char base. nessage(6¢]: » class derived « public bese ( public: erived(char *derived message, int. number} ‘void show nunber(void): private: char derived mossage(6t) b base::base(char message, int number) € strepy(base message, message): base_munber"= nunber: y derived: derived(char Yaessage, tnt nunber) curber) base("Base message” strepy(derived nessage. message): void derived: :show_munber (void) cout << “The base-class number 4s " << base_nunber << endl: y vote main(vord) € derived object("HelT0, world”, 1001 ): ‘object. show nunber(): y La compilarea si executia acestul program, pe ecran va aparea CAs PROTECT. The base-class number is 200% oo Exersati acest program. De exemplu, Incercati si addugati urmatoarele instruc- luni la funetia main: 130 4: Mostenirea claselor Void nain(void) derived cbjecti"HeTI0, world”, 1001 9; object. show_nurber () cout << “The base-clase murber 1s “<< base,nunber << endl; y Deoarece prograrul nu are acces la membril protejati ai clasei, compilatorul va genera erori de sintaxa. ier ® class base ¢ public | base(char nane(64]. int value) | void show base( void): protected: 5 . char fenenet64]: ‘ Yona size private ‘nt sone_value ‘Si INTELEGEM MEMBRI PROTEJATI AI UNEI CLASE Clasele derivate nu au acces la membri de tp private ai cla- sel de baci, Exist stuaftcind clasele derivate treble s& princescd dept speciale de acces la membri casei de| bezi. Atunc se pot folosi membri prota al clasei de baz, tare sunt aces de cate clasele derivate, dar nu stain Site pani ale programulu. De exemplu, daté find urmatoa- rea define de casa, casele derivate au acces la membri Ilename si size, dar nu sila variabila membru some value de tip private: L REZUMAT Mostenirea consia in folosirea unel clase de baz& pentru a deriva o noua clas. Mostenirea multipla constd in folosirea a dovd sau mai multor clase pentrs a deriva o alté clasd, Aga cum afi Invalat in acest capitol, C++ suporta complet atét mostenirea simplé, ct si mostenirea multipla. Folosind avantajul moste- nil, se poate economisi cod de program prin exploatarea relatilor intre obiec- te. Mostenirea este un concept cheie folosit in proiectarea si programarea orien- tata pe obiecte. inainte de a trece la Capitolul 5, asigurati-va 8 ai! invaitat urma- toarele: 131 Succes cu C++ 7 Mosenrea ae le tune cdo cass deriva pata (imosteneste) caracteristici (membri) similare acl de ba Aceasa vi perites4economis imp programe. La folosrea moyen, se pot ula in continue cons toa niaitarea claseon, dat constuctonlClasel derivate trebule ‘sh apelee consritorl clsel de bask, Puncile Constructor al cise dervate Tolosese 0 sina simiara dee sel co sido utd constr oe Y Sintaxa este stinta" programa orientate object. tp de prosramare ncepe stun! edn webule $f determina) ainbuee ce apatn clase de bazh gf cele La proiettarea ciaselor, pot apirea situatii cénd anumite clase folosesc caractersticle a doud sau mat multor clase de baz, Aceasta este mostenirea multipl Cand o clas& este derivatd din doua 7 i din doua sau mai multe clase, Caasele de baza se separa prin virgule. ‘ Mostenirea pe mai mute nivele are loc c&nd 0 clasa je are loc cand o clasa este dervata dint-o clasd de baza, care, la randul ef, este deri vata din alta clas, , {amar proejt a unel ease poate fdect accesbil de ciasele derivate, dar imposbil de apelat gin alté parte a programului, Acest tip de membru se foloseste pentru a ‘oferi membrior cerivati acces direct la membriiclasei de ‘baz, in acelasi timp protejandusi pe acestia din urma de restul programuti. 320 CAPITOLUL 5 ACOMODAREA CU SUPRAPUNEREA FUNCTIILOR $1 OPERATORILOR - : — prin crearea claselor in programele C++, se obtin proprill tipuri de date. tn ensul cel mai simplu, un tip defineste un set de valori de date ce pot fi memo- fate gi un sel de operati ce se pot efectua cu aceste date. De exemplu, 0 varia Bild de ip int poate memora valor inte in domeniul -32 768, 32 767. Operatile ce pot fi realizate cu aceasté variabilé sunt adunarea, scdderea, inmulirea, i parfirea si mai mtite operat bit cu bit. La crearea claselor, este de dort ca unele operatii sa fie exprimate prin opera: tor, De exemplu, s& presupunem ci intr-un program se foloseste o variabilé & nei clase ce exprima data sub forma 21, lund, an. Daca se doreste adunarea a 30 de zile la data, sau scéiderea a 15 zile din data, operatorii plus si minus pot produce un cod foarte inteligibil, de forma: invoice date = order date + 20: first notice = imoice date - 18: Aveti in vedere, totusi, c& variabilele membru ale clasei contin campurile 2, tuna gi an. Pentr. ca operatori plus si minus s& alba sens, programpl trebule $8 defineasca operaille ce vor trebul efectuate la intélnirea acestor operatori, Cu faite cuvinte, programul va efectua un anumit set de operatii (probabil adunarea giscdderea) cénd va intalni operatorti plus si minus folosii cu variabile de tip nt Sau float, si alt set de operatii cind va intalni aceiasi operator folosit} cu varia bilele clasei de cate. Suprapunerea operalurilor este proces! de atribuire a {oud sau a mai mullor operatii acelulas! operator. Prin folosirea operatorior su pradefinij, textul programului poate deveni foarte natural si usor de injeles. ‘Rest capitol aralizeazd in detaliu suprapunerea operatorilor si a functillor Cand vel termira de citit capitolul, veli constata c& suprapunerea operatoriior ‘este un concept ugor $1 puternic, precum si ati affat urmatoarele: ‘+ Cereprezinta suprapunerea functillor 1+ Cand doud functi distinete au acelasi nume, cum determina C++ alegerea functiel ce va fiapelata © Cum se imbunatateste claritatea programului prin suprapunerea functilor 133° Succes cu C++ + Utilzarea parametritor prestabitit + Cedi de facut cand se folosese parametti, al decdt cei prestabilit + Cum se ereeaza o biblioteca de funet + Cereprezinté suprapunerea operatorilor + Cum deterrgina compilatorul C++ operatia doris + Cum se supraineared un operator * Ce operator permit suprapunerea in C++ + Cumse foloseste un operator suprapus * Cum se creeazi un operator suprapus cu acces Ja structure membru ale unei clase ‘SA INTELEGEM SUPRAPUNEREA FUNCTILOR Inainte de @ examina suprapunerea operator, est important de a inelege suprapunerea functiilor. Aga cum veti vedea, ambele concepte sunt destul de asemnitoae mplementate de complatoarele C+ Suprapunerea fune- Ullor este procesul de define a doud sau mal mullor nei felosind aceag hme, cae fra nual pin pul de dae returnat sa prin numa tpl pa teeter, Cpls va eterna care ance tebe ape pe era Modul in eae aceasta ete folos. De exempl, utmitora progam, OVERLOAD.CH,creaed dou func enumite show message Pr ance nar partie pri simp aigeaz4un mesa A doua une primes ca parareira un giede eaactere: #include Jong sun_array(t1t *array, int nun_elesents) ¢ Jong sum = Ol: for (int 1 = 2: 4 < num_elenent: sunt array{i}: return(su) d votd matn(void) . { 135

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