Guida C++: Aspetti Avanzati
<1>
Guida C++ Aspetti Avanzati
#Name: Guida C++: Aspetti Avanzati #Author: Giuseppe_N3mes1s #Licence: GNU/GPL #!"ai: dottor$e%i_mister&tiscai'it #(eveopment: 3)/1*/*))
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<2>
Con ,uesta Guida vorrei apportare e mie conoscenze su C++ ad atri utenti- rendendomi partecipe di aumentare un po a conoscenza su ,uesto Lin.ua..io di pro.rammazione' La .uida presuppone che utente a00ia .ia una discreta se non ottima preparazione 0asiare suaro.omento- in ,uanto- a codesta non parte parte da come si crea un heo 2ord4ma i suo percorso inizia da- su cose a pro.rammazione moduare in C++- 5ino ad arrivare ae 6trutture dati Astratte' 7 tutto e composto da .uide scritte da me- prendendo spunto da testi universitari' (opo aver 5atto ,uesta sempice premessa possiamo iniziare con indice d e.i ar.omenti e poi passeremo ad appro5ondire o.nuno di essi' 6auti e 8uon Prose.uimento di 6tudio
Giuseppe_N3mes1s
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<2>
Con ,uesta Guida vorrei apportare e mie conoscenze su C++ ad atri utenti- rendendomi partecipe di aumentare un po a conoscenza su ,uesto Lin.ua..io di pro.rammazione' La .uida presuppone che utente a00ia .ia una discreta se non ottima preparazione 0asiare suaro.omento- in ,uanto- a codesta non parte parte da come si crea un heo 2ord4ma i suo percorso inizia da- su cose a pro.rammazione moduare in C++- 5ino ad arrivare ae 6trutture dati Astratte' 7 tutto e composto da .uide scritte da me- prendendo spunto da testi universitari' (opo aver 5atto ,uesta sempice premessa possiamo iniziare con indice d e.i ar.omenti e poi passeremo ad appro5ondire o.nuno di essi' 6auti e 8uon Prose.uimento di 6tudio
Giuseppe_N3mes1s
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<3>
7ndice: ➢
Pro.rammazio Pro.r ammazione ne "odua "oduare re in C++9
pa. '/
➢
La ;ic ;icors orsion ione9 e9
pa. '/1 '/13 3
➢
pa. '/1=
➢
7ntroduzione aa Pro.rammazione ad >..etti ed i C++9
pa. '/1?
➢
redita re ditarie riet@9 t@9
pa. '/* '/*
➢
Poimo Po imor5i r5ismo9 smo9
pa. '/3 '/3
➢
Le Cassi: notazi notazioni oni di 0ase de C++9
pa. '/3
➢
Punt Pu ntato atori ri99
pa. pa . '/ '/= =
➢
Cassi di memoriz memorizzazion zazionii dee varia0 varia0ii ii in C++9
pa. '/)
➢
Conversione Conver sione di tipo Bcasti Bcastin. n. in C++9
pa. '/
➢
;ide5inizione ;ide5in izione de.i operat operatori9 ori9
pa. '/D
➢
7 6is 6istema tema di 7/> in C++ C++99
pa. '/==
➢
6trutt 6tr utture ure (at (atii Astr Astratt atte' e'
pa. '/D
➢
Conc Con cus usion ionii
pa. '/ '/D? D?
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<4>
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<5>
Programmazione modulare in C++ Meccanismi per la modularizzazione Aspetti concettuali relativi alla modularizzazione Nea 5ase de pro.etto di un so5t2are ven.ono utiizzate ade.uate meta5ore per ra..ruppare e parti di so5t2are che costituiscono ne oro insieme un pro.ramma9 ,uesta operazione viene detta "oduarizzazione de pro.ramma e viene reaizzata utiizzando opportuni meccanismi di moduarizzazione' Il ciclo di sviluppo dei programmi 7 cico di sviuppo di un pro.ramma prevede una serie di 5asi atte a con5erire si.ni5icative 5essi0iit@: a composizione di un pro.ramma di .rosse dimensioni attraverso piu modui9 – –
uso di 0i0ioteche di 5unzioni .ia compiate9
–
i coe.amento di modui .ia precedentemente scritti con diversi in.ua..i di ori.ine9
–
a possi0iita di porre su mercato- pro.rammi o modui non in 5orma ori.ine ma in 5orma o..etto9 e ,uesta a sceta di moti produttori per motivi di tutea dea proprieta'
7 cico di sviuppo dei pro.rammi ricaca e se.uenti 5asi che verranno eencate: Preparazione testo origine: –
7 testo ori.ine viene preparato mediante un editor e viene savato con estensione 'cpp9
–
7 codice sor.ente di una appicazione viene- in .enerae- strutturata in piu moduiredatti da piu pro.rammatori9
–
Ciascuna unita di traduzione viene sottoposta separatamente ae successive 5asi di precompiazione e compiazione9
La struttura di un .enerico moduo e i se.uente: – – – – – –
(irettive di precompiazione9 (ichiarazioni di nomi di tipo9 (ichiarazioni di costanti e varia0ii9 (ichiarazioni di 5unzioni Bprototipi9 (e5inizione di costanti e di varia0ii9 (e5inizione di 5unzioni'
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<6>
Precompilazione –
7 testo ori.ine Bsor.ente contenuto ne 5ie 'c/'cpp viene ea0orato da un pro.ramma detto preprocessore Bprecompiatore che modi5ica i codice se.uendo acune direttive date.i da pro.rammatore9
–
Le direttive a preprocessore sono contenute nee ri.he di testo che cominciano co carattere # Bcanceetto- sharp- pound9
–
Loutput de precompiatore e codice sor.ente che va a compiatore vero e proprio'
Compilazione delle unita' –
–
Le unita de pro.ramma ven.ono compiate separatamente mediante attivazione de compiatore9 Per ciascuna unita di traduzione- i testo ori.ine viene tras5ormato in 5ie o..etto e viene savato in un 5ie con estensione 'o0$ Boppure 'o'
Il file oggetto –
7 5ormato de 5ie o..etto e indipendente da in.ua..io ad ato iveo9
–
Un 5ie contiene- otre a codice macchina: ! una ta0ea di sim0oi B5unzioni e varia0ii esterne o .o0ai de5inite ne corrispondente 5ie sor.ete9 !! una ta0ea dei sim0oi utiizzati ma non de5initi ne moduo B,uindi de5initi in atri modui9
–
Era e in5ormazioni presenti tavota vi sono anche i dati per i de0u..in.'
Collegamento (linkage) –
7 diversi modui o..etti costituenti i pro.ramma Bp1'o-''-pn'o ven.ono com0inati 5ra oro ed assieme a supporto a tempo di esecuzione- mediante un pro.ramma coe.atoreBin%er9
–
7 coe.atore traduce i testo ese.ui0ie de pro.ramma in un unico 5ie Besempio: pro.'eFe9
–
Anche se i pro.ramma consta di un soo 5ie sor.ente- acune i0rerie sono 5ondamentai Bad esempio ,uee di in.resso/uscita9
–
7 in%er puo se.naare errori- tipicamente perche non e possi0ie associare ad un sim0oo richiesto da un moduo acun sim0oo tra ,uei esportati nei modui9
–
Cio puo avvenire in acuni dei se.uenti casi: ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<7>
!! ci si e dimenticati di indicare ,uache 5ie'cpp a in%er9 !! manca impementazione di ,uache 5unzione9 !! esistono piu de5inizioni di uno stesso nome di 5unzione o varia0ie .o0ae' Ambiente di sviluppo Un am0iente di sviuppo di pro.rammi di un .enerico in.ua..io o55re come strumenti essenziai: –
Compiatore9
–
Coe.atore9
Acuni strumenti moto di55usi sono: –
–
ditor9 Anaizzatori/veri5icatori di codice9
–
Pro.ramma di .estione automatica dei passi di compiazione e coe.amento Bma%e9
–
(e0u..er9
–
Pro.ramma di creazione di i0rerie di moduo o..etto9
–
Generatori automatici di codice9
–
6o5t2are di .estione dea con5i.urazione so5t2are'
Gi am0ienti di sviuppo inte.rati Bdetti 7( ra..ruppano tai strumenti sotto ununica inter5accia: –
8orand Eur0o Pasca Binter5accia testuae a menu9
–
8orand C++ 8uider Binter5accia .ra5ica e pro.rammazione visuae9
–
(ev!C++ Binter5accia .ra5ica e pro.rammazione visuae9
Modularizzazione Luso discipinato di acuni meccanismi de in.ua..io C++ consente una corretta strutturazione di un pro.ramma in modui' Era i principi di meccanismo ci sono: –
a compiazione separata9 ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
–
incusione testuae9
–
e dichiarazione extern9
–
uso dei prototipi di 5unzione9
<8>
Specifica ed implementazione 0uona norma tenere separata a speci5ica di un moduo daa sua impementazione' Un pro.ramma utente di un moduo A deve conoscere a sua speci5ica- ma disinteressarsi dei detta.i dea sua impementazione' Cio puo essere reaizzato scrivendo un 5ie di intestazione o header file Bcon estensione 'h contenente e dichiarazioni che costituiscono inter5accia di A- ed un 5ie separato per impementazione di A' Lheader 5ie deve essere incuso Bmediante a direttiva a preprocessore #include nea impementazione- ed o.ni moduo utente- a55inche i compiatore possa ese.uire i controi necessari' esempio: un pro.ramma C++ consiste di piu 5ie sor.enti che sono individuamente compiati in 5ie o..etto- ,uesti poi sono coe.ati tra oro per produrre a 5orma ese.ui0ie' //fact.h long fact(long); //fact.cpp #include "fact.h" long fact(long f){ if(f<=1)return 1; return f* fact(f-1); } //main.cpp #include "fact.h" #include
6i noti- 5in tanto che inter5accia resta intatta- impemetazione puo essere modi5icata senza dover ricompiare i moduo utente Bma occorre ricoe.are i modui o..etto' La speci5ica- contenuta ne 5ie di intestazione- puo essere .uardata come una sorta di contratto sottoscritto tra impementatore e utente' uando piu pro.rammatori avorano simutaneamente ad un pro.etto di .randi dimensioni- una vota accordatisi sua speci5ica dei vari modui- possono procedere ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<9>
aimpeementazione dei ripettivi modui indipendentemente uno daatro' ibrerie dei moduli soft!are ueste tecniche di sviuppo moduare consentono o sviuppo su 0ase pro5essionae di i0rerie di modui so5t2are9 7 produttore di una i0reria distri0uisce: –
i 5ie intestazione Bche devono essere incusi dautiizzatore ne codice sor.ente dei modui che 5anno parte dea i0reria9
–
i modui dea i0reria in 5ormato o..etto B.ia compiati- che utiizzatore deve coe.are assieme ai proprio modui o..etto9
Eae sceta e tipicamente motivata da esi.enze di tutea dea proprieta- ed inotre evita di dover ricompiare i modui di i0reria' Perc"e' dividere il programma in piu' file sorgenti 7 vanta..i ne dividere i pro.ramma in piu modui ser.ente sono: –
La struttura di un pro.ramma medio!.rande e piu chiara se i pro.ramma e suddiviso in piu 5ie sor.enti9
–
Piu pro.rammatori possono avorare ao stesso tempo su 5ie diversi9
–
Non occorre ricompiare intero pro.ramma o.ni vota che si e55ettua una piccoa modi5ica9
–
6i possono usare i0rerie senza dovere incudere 5isicamente i codice sor.ente ne pro.rammaBspesso i sor.ente non e disponi0ie'
'inclusione multipla 6i puo veri5icare che a stessa i0reria ven.a incusa da due di55erenti i0rerie entram0i incuse- a oro vota- in uno stesso pro.ramma' 7n ,uesto caso- in assenza di precise precauzioni- si incudere00ero nea compiazione piu copie deo stesso codice Bcontenuto ne 5ie header- raentando i processo di compiazione' Poiche header 5ie contiene escusivamente dichiarazioni- non ha acun vanta..io incudero piu vote' Precauzioni La precauzione per evitare a dupicazione di codice consiste neutiizzare opportunamente e direttive di precompiazione' 7 particoare si usano e direttive:
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati –
#ifndef
–
#define
–
#endif
<10>
sempio: header 5ie dea i0reria iostream e reaizzato cosi: //iotream.h #ifndef &'+,& #define &'+,& ... //0ui le dichiaraioni della li2reria #endif /* &'+,& */
uesto approccio e sempre utiizzato da chi scrive i0rerie' #nicita' delle etic"ette Nonostante cio risova i pro0ema- si rende necessario che neam0ito di un intero pro.etto i nomi dee etichetteB es: _7>6E;A"_H siano univoci' 6e ,uesto re,uisito viene a mancare si possono .enerare errori dovuti aa mancata incusioni dee i0rerie' Conflitti tra nomi 7n pro.etti di dimensioni medio!.randi e possi0ie che ci siano con5itti tra nomi esportati tra due di55erenti i0rerie' uesto 5enomeno e noto come Iin,uinamento deo spazio dei nomiI' 7 C tenta di risovere i pro0ema attraverso uso di sim0oi che Iaccompa.nanoI .i identi5icatori: –
uso de carattere underscore: _identi5ier'
7 C++ o55re una metodoo.ia che risove sistematicamente i pro0ema: –
i meccanismo dei NA"6PAC'
$ic"iarare un namespace A iveo di moduo e possi0ie dichiarare un namespace ne ,uae ven.ono poi de5initi tutti i sim0oi de moduo: esempio: studenti'h #ifndef &&34,5'&& #define &&34,5'&& namepace p1tlc { t6pedef truct { ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<11>
int prefio; int matricola; char* 7ognome; char* 5ome; } tudente; e8tern tudente +appreentante; } #endif /* &&34,5'&& */
#tilizzare un namespace Per utiizzare un nome de5inito neam0ito di un namespace 0iso.na espicitamente IaprireI o spazio dei nomi' 7n caso contrario si incorre in errori di compiazione' esempi: #include "tudenti" int main() { tudente ; //genera un errore."tudente" non e9 un identificatore definito ... } #include "tudenti" int main() { p1tlc::tudente ; // ... } #include "tudenti uing namepace tudenti; //"apre" tutto lo paio dei nomi int main() { tudente ; // ... }
Lo standard C++ Convenzionamente- in C++ .i header 5ie i cui nomi terminano con 'h non 5anno uso dei namespace' uei invece che non hanno estensione- a contrario- i usano' La i0reria standard- ,uea che de5inisce anche cin e cout- de5inisce tutti i sim0oi neo spazio dei nomi std' esempi: //tile c #include
Guida C++: Aspetti Avanzati
<12>
cout << "uniona$n"; } //errore #include
o tandard 7
Convenzionamente- in C++ .i header 5ie i cui nomi terminano con 'h non 5anno uso dei namespace' uei invece che non hanno estensione- a contrario- i usano' La i0reria standard- ,uea che de5inisce anche cin e cout- de5inisce tutti i sim0oi neo spazio dei nomi std' esempi: //tile c #include
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<13>
a %icorsione 7 concetto di ricorsione in5ormatica si riconduce a concetto di induzione matematica' 6ia P un predicato suinsieme N dei numeri naturai e sia vero i predicato PB)9 se per o.ni J intero- da predicato PBJ discende a verita di PBJ+1 aora PBn e vero in ,uasiasi n' La dimostrazione dea 5orma induttiva viene dun,ue svota secondo i se.uenti passi: Passo 0ase deinduzione: dimostrare PB)Kvero9 Passo induttivo: dimostrare che per o.ni %) PB% ! PB%+1 Cosi come nea 5unzione induttiva a verita di PB%+1 descende daa verita deo stesso predicato di PB%- i cacoo di una 5unzione ricorsiva avviene mediante i cacoo dea stessa 5unzione in un passo successivo' %icorsione 7 cacoo ricorsivo sta ne 5atto di cacoare una 5unzione attraverso se stessa' esempio: a 5unzione 5attoriae N Bper interi non ne.ativi a)K1 0se n) aora n KnMBn!1 7n atre paroa a potenza dea ricorsione sta ne 5atto di poter de5inire un insieme in5inito di o..etti con una re.oa 5inita' A.oritmi ricorsivi 6ono caratterizzati da: Una 5unzione .eneratrice ! F'''K.BF' ! che produce una se,uenza di F'-F'-F'- '''- F' Un predicato pK pBF vero per FKF' Una 5unzione 5BF detta ricorsiva tae che ! 5BF'KchBF'-5BF''O ! 5BF'K 5Bse.nato Sc"ema di algoritmi ricorsivi 6ono codi5icati mediante un sottopro.ramma che richiama se stesso: @ (1 8) { ... if p(8) ;
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<14>
ele 7(A@); + } int fatt(int 8){ int f; if(8<=1) f=1; ele f=8*fatt(8-1); return f; }
&erminazione La chiamata ricorsiva deve ,uindi essere su0ordinata ad una condizione che ad un certo istante risuti non soddis5atta Bi predicato p' 7 numero dee chiamate necessarie viene detto pro5ondita dea ricorsione' Meccanismo interno della ricorsione Un sottopro.ramma ricorsivo e un sottopro.ramma che richiama direttamete o indirettamente se stesso' Non tutti i in.ua..i reaizzano i meccanismo di ricorsione' uei che o utiizzano 5anno uso di ,ueste tecniche: •
•
Gestione L7<> di piu copie dea stessa 5unzione- ciascune con i proprio insieme di varia0ii ocai .estione mediante record di attivazione9 ununica copia de sottopro.ramma ma ad o.ni chiamata e associata ad un record di attivazione'
$alla forma ricorsiva a uella iterativa Un pro0ema ricorsivo puo essere risoto in 5orma iterativa' Ne caso in cui a ricorsione e in coda i caso e sempice: ricorsivo: @(1 8) { ... if p(8) ; ele{;@(8);} return } iterativo: Bhile p(8) ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<15>
; ;
cacoo de 5attoriae: esempio: 5orma ricorsiva: int fatt(cont int 8){ int f; if (8<1) f=1 ele f=8*fatt(8-1); return f; }
5orma iterativa: int fatt(cont int 8){ int f=1Ai; for(i=1;i<8;i) f=f*i; return f; }
%icorsione ed iterazione ;icorsione: • • •
Uso de costrutto di seezione Condizione di terminazione Non conver.enza
7terazione: Uso de costrutto di iterazione • Condizione di terminazione • Loop in5inito • A di55erenza deiterazione- a ricorsione richiede un notevoe sovreccarico Boverhead a tempo di esecuzione per a chiamata di 5unzione' uando usarenon la ricorsione A.oritmi che per a oro natura sono ricorsivi piuttosto che iterativi dovre00ero essere 5ormuati con procedure ricorsive' Ad esempio acune strutture dati sono inerentemente ricorsive: ! 6trutture ad a0ero ! 6e,uenze ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<16>
! ''' a 5ormuazione di strutture ricorsive su di esse risuta piu naturae' La ricorsione deve essere evitata ,uando esiste una souzione iterativa ovvia e in situazioni in cui e prestazioni de sistema son un eemento critico
*unzioni aspetti avanzati Il passaggio dei parametri Un parametro e di 7NG;66> per un sottopro.ramma se i suo vaore viene soo utiizzato Bmai asse.nato ne modi5icato da sottopro.ramma' Un parametro e di U6C7EA per un sottopro.ramma se i suo vaore viene asse.nato da sottopro.ramma' Un parametro e di 7NG;66>!U6C7EA per un sottopro.ramma se i suo vaore viene prima utiizzato- poi riasse.nato o modi5icato da sottopro.ramma' 7 paramatri di in.ressi per un sottopro.ramma vanno scam0iati mediante passa.io per vaore: ?oid tampa(cont int 8) // 8 parametro formale { cout<<8; } int 2; tampa(2); // 2 param. effett.
7 passa..io per vaore di un ar.omento viene reaizzato da compiatore copiando i vaore de parametro e55ettivo ne corrispondente parametro 5ormae- aocato neo stac% 5rame dea 5unzione' 7 parametri di uscita- o ,uei di in.resso!uscita vanno scam0iati tramite puntatori o mediante passa..io per ri5erimento' 7 passa..io tramite puntatore e totamente a cura de pro.rammatore- e consiste ne 5atto di passare per vaore i puntatore aa varia0ie: ?oid incr(int *?) { *? = 1; } int a = C; incr(Da);// ora "a" ?ale E
I parametri di riferimento 7n aternativa in C++ esiste i passa.i.io per ri5erimento' ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<17>
Un parametro di ri5erimento e un aias dea varia0ie ar.omento' 7 passa..io per ri5erimento e e55iciente in ,uanto evita a copia de vaore' 7 parametro 5ormae in reata e un puntatore che contiene indirizzo di ri5erimento de parametro e55ettivo' 7 passa..io deindirizzo Bdere5erencin. de ri5erimento e a cura de compiatore' ?oid incr(int D?) { ? = 1; } int a = C; incr (a); // ora "a" ?ale E
I riferimenti 7 ri5erimenti sono in ,uache modo e,uivaenti a dei puntatori costanti: C r e,uivae a
CM const p
La di55erenza sta ne 5atto che ne caso dei ri5erimenti e asciato a compiatore i compito di distin.uere tra i ri5erimento ed i vaore ri5erito9 ne caso dei puntatori i pro.rammatore deve espicitamente indicare dove vuoe operarese su puntatore o su vaore puntato' Luso dei ri5erimento e dun,ue meno incine a.i errori' ssi devono rispettare e se.uenti re.oe: ! un ri5erimento deve essere iniziaizzato ,uando e creato ! una vota creato un ri5erimento non puo essere modi5icato ! non e possi0ie avere un ri5erimento NULLB) esempio: int 8; int D r = 8; //r e9 un riferimento ad 8 r=F; // r e9 un l-?alue e dun0ue un indirio int G=r; // r e9 un r-?alue e dun0ue un ?alore ,li argomenti di dafault Gi utimi oppure tutti i parametri di una ista possono avere dei vaori di d a5aut' i prototipo che deve speci5icare .i ar.omenti di de5aut' 6e invocazione dea 5unzione non speci5ica .i utimi ar.omenti- ,uesti ven.ono assunti u.uai a.i ar.omenti di da5uat' esempio: ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<18>
?oid a2c(int 8A int 6=1A char *p="hello"); ... ?oid 86() { a2c(1A "6ahtee");//il compilatore aocia 6ahtee al parametro 6 e egnala errore }
'overloading delle funzioni 7n C++ e possi0ie dare a 5unzioni diverse o stesso nome- a condizioni che e 5unzioni a00iano iste di parametri diversi Bin numero e/o tipo' 7 compiatore e in .rado di associare in modo univoco ciascuna chiamata a una dea 5unzioni- distinte in 0ase aa ista de.i ar.omenti' esempio: // ?erione ?oid incr(int *?) { *?; } // ?erione H ?oid incr(int *?A int d8) { *? = d8; } // ?erione 7 ?oid incr(float *?) { *? = *? 1.%; } float 8=%.; incr(8); // ?iene in?ocata // la ?erione 7
Avere tipi di ritorno diversi non e su55iciente a distin.uere e 5unzioni' Neistruzione di chiamata in5atti puo non essere evidente i tipo de vaore di ritorno' Un uso poco attento dei parametri di de5aut puo causare am0i.uita' ?oid o?l(char=9a9); ?oid o?l(int=%); III o?l();
uando uno stesso nome e associato a piu 5unzioni- si dice che ,uesto nome e sovraccaricato Boveroaded di si.ni5icato' <7;"A Bsi.nature di una 5unzione: • ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
•
•
<19>
nome + tipo dei parametri 7n presenza dea chiamata di una 5unzione overoaded- i compiatore riconosce ,uea me.io adatta aa chiamata 7 tipo restituito non 5a parte dea 5irma dea 5unzione'
Loveroadin. dee 5unzioni si usa: uando si devono de5inire 5unzioni concettuamente simii da apicare a dati di tipo • diverso La.oritmo utiizzato da ciascuna 5unzione e anchesso diverso a seconda dei tipi di • dato a cui a 5unzione deve essere appicata' e funzioni inline Le 5unzioni inine sono 5unzioni a cui chiamate non sono tradotte in in.ua..io macchina da compiatore mediante sato a sottopro.ramma 7 codice dea 5unzione viene inserito in inea- cioe ne punto dea chiamata Luso dee 5unzioni inine deve essere imitato a 5unzioni da corpo moto 0reve atrimenti: i mi.ioramento de tempo di esecuzione e irrievante • aumento dea dimensione de codice puo essere notevoe • Le 5unzioni inine devono essere de5inite neo stesso 5ie in cui sono invocate- ovvero in un 5ie di intestazione Bheader 5ie da importare- perche i compiatore deve co noscerne i corpo per sostituiro ad o.ni chiamata: non sempre una 5unzione inine viene sviuppata in inea da compiatore • non puo essere esportata • Una 5unzione inine puo speci5icare ar.omenti di da5aut: inline int plune(int 8=%) { return 8; } int main() { cout <<"$n inline:"<
Introduzione alla programmazione ad -ggetti e il C++ Acuni principi dein.e.neria de so5t2are: • • • •
Astrazione9 "oduarita9 7ncapsuamento ed in5ormation hidin.9 Limportanza dee astrazioni9
'Astrazione
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<20>
Lastrazione e i processo che porta ad estrarre e proprieta rievanti di unentitain.norando pero i detta.i inessenziai' Le propieta estratte de5iniscono una vista deentita9 Una stessa entita puo dar uo.o a viste diverse9 a Modularita' La moduarita e or.anizzazione in modui di un sistema- in modo che o stesso risuti piu sempice da capire e manipoare' Un moduo di un sistema so5t2are e un componente che: reaizza unastrazione9 e dotata di una chiara separazione tra: ! inter5accia9 ! corpo9 Linter5accia speci5ica cosa 5a i moduo e come si utiizza' 7 corpo descrive come astrazione e reaizzata' 'incapsulamento e information "iding Lincapsuameno consiste ne InascondereI e Iprote..ereI acune in5ormazioni di unentita' Laccesso in maniera controata ae in5ormazioni nascoste e poss0ie .razie a varie operazione descritte dainter5accia' 'importanza delle astrazioni Eutti i in.ua..i di pro.rammazione o55rono diversi tipi di astrazione: • • •
tipi sempici9 strutture di controo9 sottopro.rammi9
Lastrazione 5ondamentae dei in.ua..i ad o..etti e astrazione sui dati' Meccanismi di astrazione Nea pro.ettazione di un sistema so5t2are e opportuno adoperare dee tecniche di astrazione atte a dominare a compessita de sistema da reaizzare' 7 meccanismi di astrazione piu di55usi sono: • •
A6E;AQ7>N 6UL C>NE;>LL>9 A6E;AQ7>N 6U7 (AE79
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<21>
Astrazione sul controllo Consiste neastrarre una data 5unzionaita nei detta.i dea sua impementazione9 0en supportata dai in.ua..i di pro.rammazione attraverso i concetto di sottopro.ramma' Astrazione sui dati Consiste neestrarre entita Bo..etti constituenti i sistema- descr itte in termini di una struttura dati e dee operazioni possi0ii su di essa9 Puo essere reaizzata con uso opportuno dee tecniche di pro.ramazione moduare nei in.ua..i tradizionai9 supportata da appositi costrutti nei in.ua..i di pro.rammazione ad o..etti' Metodologie di progetto &op.$o!n e /ottom.#p La metodoo.ia discendente- cioe top!do2n- e 0asata suapproccio di decomposizione 5unzionae nea de5inizione di in sistema so5t2are- cioe suindividuazione dee 5unzionaita de sistema da reaizzare e su ra55inamenti successivi- da iterare 5inche a scomposizione de sistema individua sottoinsieme di compessita accetta0ii' La metodoo.ia ascendente- cioe 0ottom!up- e 0asata suindividuazione dee entita 5acenti parte de sistema- dee oro proprieta reazioni tra di esse' 7 sistema viene costruitoassem0ando componenti on unapproccio da 0asso verso ato' a programmazione procedurale Usa come metodoo.ia di ri5erimento a decomposizione 5unzionae- con approccio discendente ,uindi top!do2n' 6i scompone ricorsivamente a 5unzionaita principae de sistema da sviuppare in 5unzionaita piu sempici' 6i termina a scomposizione ,unado e 5unzionaita individuate sono cosi sempici da permettere una diretta impementazione come 5unzioni' 6i divide i avoro di impementazione- eventuamente tra diversi pro.rammatori- sua 0ase dee 5unzionaita individuate' a programmazione ad oggetti 6i individuano a cassi di o..etti che caratterizzano i dominio appicativo: e diverse cassi ven.ono poi modeate- pro.ettate ed impementate9 o.ni casse e descritta da uninter5accia che speci5ica i comportamento de.i o..etti dea casse' Lappicazione si costituisce con approciio ascendente- 0ottom!up- assem0ando o..etti e individuando a modaita con cui ,uesti devono coa0orare per reaizzare e 5unzionaita deverse deappicazione' ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<22>
&ipi di dati astratti 7 concetto di tipo di dato in un in.ua..io di pro.rammazione tradizionae e ,ueo di insieme dei vaori che un dato puo assumere Bvaria0ie' 7 tipo di dati stratto incude in ,uesto insieme- estendendone a de5inizione- anche insieme di tutte e soe e operazioni possi0ii su dati di ,ue tipo' La struttura dati competa e incapsuata nee operazione da essa de5inite' Non e possi0ie accedere aa struttura dati incapsuata- ne in ettura ne in scrittura- se non con e operazioni de5inite su di essa ' 7nter5accia: speci5ica de E(ABtipo dato astratto- descrive a parte direttamente accessi0ie dautiizzatore9 ;eaizzazione: impementazione de E(A' Produttore e utilizzatore 7 ciente 5a uso de E(A per reaizzare procedura di unappicazione- e per costruire E(A piu compessi9 7 Produttore reaizza e astrazioni e e 5unzionaita previste per i dato' Una modi5ca aoa aa reaizzazione de E(A non in5uenza i modui che ne 5anno uso' &ecnic"e di programmazione ad oggetti 6i para di pro.rammazione con o..etti con ri5erimento a tecniche di pro.rammazione 0asate su concetto di o..etto' 6i para di pro.rammazione 0asata su.i o..etti Bo0$ect!0ased pro.rammin. con ri5erimento ae tecniche di pro.rammazione 0asate sui concetti di: Eipo di dato astratto o CasseBtipo9 >..etto Bistanza de tipo' 6i para di pro.rammazione orientata a.i o..ettiBo0$ect oriented pro.rammin.- >>P co ri5erimento ae tecniche 0asate sui concetti: Casse9 • >..etto9 • reditarieta9 • Poimor5ismo' • inguaggi ad oggetti possi0ie adottare tecniche di pro.rammazione con o..etti o 0asate su.i o..etti anche in un.ua..i tradizionaiBpasca- c adoperando opportune discipine di pro.rammazione- aderendo cioe ad un insieme di re.oe i cui uso pero non puo essere ne ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<23>
5orzato ne veri5icato da compiatore' Un in.ua..i di pro.rammazione ad o..etti o55re costrutti espiciti per a de5inizione di entita- o..etti- che incapsuano a struttura dati nee operazioni su di essa' Acuni in.ua..i- in particoare i C++- consentono di de5inire tipo astratti- e ,uindi istanze di un dato di tipo astratto' 7n ta caso i in.ua..io 0asato su.i o..etti presenta costrutti per a de5inizione di cassi e di o..etti' sistono dun,ue in.ua..i ad o..etti: Non tipizzati: s 6mata% • possi0ie de5inire o..etti senza dichiararne i tipo • 7n tai in.ua..i .i o..etti sono entita che incapsuano una struttura dati nee • operazioni possi0ii su di essa' Eipizzati: s C++- Rava • possi0ie de5inire tipo di dati astratti ed istanziari' • Gi o..etti devono appartenere ad un tipo' • 7n tai in.ua..i- una casse e una impementazione di un tipo di dato astratto' Un • o..etto e una istanza di una casse' Il linguaggio C++ C++ e un in.ua..io di pro.rammazione .enera!purpose che supporta: La pro.rammazione procedurae • La pro.rammazione orientata a.i o..etti • La pro.rammazione .enerica • 7 c++ e dun,ue un in.ua..io Ii0ridoI ne senso che supporta piu paradi.mi di pro.rammazione' Classi ed oggetti Ne in.ua..i a o..etti- i costrurro casse consente di de5inire nuovi tipi di dati astratti e e reative operazione connessi ad essi' 6otto 5orma di operatori o di 5unzioni Bdette 5unzioni mem0ro- i nuovi tipi di dato possono essere .estiti ,uasi ao stesso modo dei tipi prede5initi da in.ua..io: si possono creare istanze9 • si possono ese.uire operazioni su di esse9 • Un o..etto e una varia0ie istanza di una casse' Lo stato di un o..etto e rappresentato dai vaori dee varia0ii che costituiscono a ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<24>
struttura dati concreta sottostante i tipo astratto' 0reditarieta' e Polimorfismo Lereditarieta consente di de5inire nuove cassi per speciaizzazioni o estensioni per cassi .ia preesistenti- in modo incrementae' 7 poimor5ismo consente di invocare operazioni su un o..etto- pur non essendo nota a tempo di compiazione a casse a cui 5a ri5erimento o..etto stesso' 0reditarieta' 7 mecaniscmo di ereditarieta e 5ondamentae nea pro.rammazione ad o..etti- in ,uanto prevede a strutturazione .erarchica ne sistema so5t2are da costruire' Lereditarieta in5atti consente di reaizzare reazioni tra cassi di tipo .eneraizzazione! speciaizzazione- in cui- una casse- detta 0ase- reaizza i comportamento .enerae comune ad un insieme di entita- mentre a cassi derivate reaizzano comportamenti speciaizzati rispetto a ,uei dea casse 0ase' Generaizzazione: da particoare a .enerae 6peciaizzazione o particoarizzazione: da .enerae a particoare siste pero un atro motivo per utiizzare ereditarieta otre a ,ueo di or.anizzazione .erarchica- ed e ,ueo de riuso de so5t2are' 7n acuni casi si ha una casse che non corrisponde proprio ae nostre esi.enze- anziche scartare i tutto e riscrivere i codice- con ereditarieta si puo se.uire un approccio diverso- costruendo una nuova casse che eredita i comportameto di ,uea esistente- save pero che per ,uei com0iamenti che si ritiene necessario apportare' Eai cam0iamenti posso portatre aa..iunta di nuove 5unzionaita o aa modi5ica di ,uee esistenti' 7n de5initiva ereditarieta o55re un vanta..io anche in termini di sviuppo perche riduce i tempi- in ,uanto: minimizza a ,unatita di codice da scrivere non e necessario conoscere in detta.io i 5unzionamento de codice d a riutiizzare ma e su55iciente modi5icare a parte di interesse' Polimorfismo Per poimor5ismo si intende a propieta deentita di assumere 5orme diverse ne tempo' Con unentita poimor5a si puo 5are ri5erimento a cassi diverse' 6i consideri una 5unzione (ise.na_
Guida C++: Aspetti Avanzati
<25>
Lesecuzione de cico richiede che sia possi0ie determinare dinamicamente Bcioe a tempo desecuzione impementazione dea operazione dise.naB da ese.uire- in 5unzione de tipo corrente deo..etto A i O' Listruzione A i O'dise.naB non ha 0iso.no di essere modi5icata in conse.uenza dea..iunta di una nuova sottocasse di
•
•
•
•
moduarita: a cassi sono i modui de sistema so5t2are9 coesione dei modui: una casse e un componente so5t2are 0en coeso in ,uanto rappresentazione di un unica entita9 disaccopiamento dei modui: .i o..etti hanno un ato .rado di disaccoppiamento in ,uanto i metodi operano sua struttura dati interna ad un o..etto9 i sistema compessivo viene costruitocomponendo operazioni su.i o..etti9 in5ormation hidin.: sia e strutture dati che .i a.oritmi possono essere nascosti aa visi0iita daesterno di un o..etto9 riuso: ereditarieta consente di riusare a de5inizione di una casse ne de5inire nuove Bsottocassi9 inotre e possi0ie costruire i0rerie di cassi ra..ruppate per tipoo.ia di appicazioni9 estensi0iita: i poimor5ismo a.evoa a..iunta di nuove 5unzionaita minimizzando e modi5iche necessarie a sistema esistente ,uando si vuoe estendero'
0reditarieta' 'ereditarieta' nella programmazione soft!are Lereditarieta e di 5ondamentae importanza nea pro.ettazione ad o..etti- poiche induce ad una strutturazione di tipo .erarchico ne sistema so5t2are ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<26>
da reaizzare' ssa consente in5atti di reaizzare ,ue sistema detto .erarchia di .eneraizzazione!speciaizzazione- seconda a ,uae esiste a casse- detta 0ase- che reaizza i comportamento .enerae- comune ad un inseme di entita- mentre e cassi derivate reaizzano i comportamento particoare de.i o..etti dea .erarchia- speciaizzandoo rispetto a ,ueo dea 0ase' Ciascun o..etto dea casse derivata e anche o..etto dea casse 0ase ed eredita cosi tutti i comportamenti dea casse 0ase ed in piu a..iun.e i comportamenti impementati in essa' Non e vero i contrario invece' 'ereditarieta' come riuso del soft!are siste pero anche un atro motivo- di ordine pratico- per cui conviene usare ereditarieta' >tre a ,ueo di descrivere un sistema secondo un ordine .erarchico- ce un atro concetto che e e.ato a riuso de so5t2are' 7n acuni casi si ha a disposizione una casse che non corrisponde propriamente ae nostre esi.enze9 anziche scartare tutto i codice esistente e riscrivero- si puo se.uire con ereditarieta un approccio diverso- costruendo una nuova casse che eredita i comportamento di ,uea esistenza- pero adattandoa ae nostre esi.enze' uesto approccio o55re i vanta..io di ridurre i tempi deo sviuppo de sot2are- perche minimizza a ,uantita di codice da scrivere- riducendo anche a possi0iita di cadere in errori' 7notre non e necessari conoscere i 5unzionamento de codice compessivo- ma e su55iciente modi5icare a parte di interesse' 7n5ine poiche i so5t2are e .ia stato veri5icato- a parte di test risuta sempi5icata' I meccanismi sintattici per la derivazione 6truttura dea casse derivata 6upponiamo che sia stata de5inita una casse 0ase:
7 pro.ettista di una nuova casse- di nome (erivata- puo de5inire a nuova casse ,uae derivata dea casse 8ase:
Guida C++: Aspetti Avanzati
<27>
#include "Hae.h" clae deri?ata:pu2lic Hae{//deri?ata ereditata da Hae pu2lic: //funioni mem2ro L ?oid g1();//funione mem2ro g1 ... ?oid gm();//funiome me2ro gm pri?ate: //?aria2ili mem2ro 2eta };
a casse (erivata eredita tutte e 5unzioni e e varia0ii mem0ro dea casse 8ase e de5inisce a sua vota uteriori varia0ii mem0ro 0eta e 5unzioni G' Meccanismi e diritti di accesso Aspetto generale Per ,uanto ri.uarda i diritti di accesso- vae i concetto .enerae secondo i ,uae nessun meccanismo puo vioare e protezioni de5inite da pro.ettista dea casse' 7n particoare- una casse derivata non possiede nessun privie.io speciae per accedere aa parte private dea casse 0ase: se cosi 5osse si potre00e in5ran.ere a privatezza di una data casse sempicemente de5inendo una casse derivata ad essa' La casse derivata dun,ue eredita varia0ie e 5unzioni mem0ro dea casse 0ase ma accede a tai comportamenti secondo i meccanismi che sono stati speci5icati nea casse 0ase' Le 5unzioni mem0ro dea casse derivata possono accedere: a tutti i mem0ri dea casse derivata- indipendentemente daa oro modaita di • protezione ai mem0ri pu00ici dea casse 0ase • Accesso delle funzioni membro e funzioni utente Per ,uanto attiene i pro.ramma che utiizza a .erarchia di derivazione- esso puo de5inire o..etti dea casse 0ase e o..etti dea casse derivata e accedere- secondo i consueti meccanismi di accesso- ae componenti pu00iche di 8ase e (erivata' 7notre utiizzando i meccanismi 5orniti daereditarieta- i pro.ramma utente puo accedere aa componenti pu00iche de sotto!o..etto 0ase dea casse derivata e puo appicare a ,uestutimo a 5unzioni de5inite daa casse 0ase' •
•
•
Le 5unzioni mem0ro di 8ase accedono ai componenti pu00ici e privati de sotto! o..etto 0ase9 Le 5unzioni mem0ro dea (erivata accedono a componenti pu00ici de sotto! o..etto 0ase e ai componenti pu00ici e privati dea parte proprio di (erivata9 Le 5unzioni utente di (erivata accedono a componenti pu00ici de sotto!o..etto ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<28>
0ase e dea parte propria di derivata' -verriding e -verloading 7 meccanismo di ride5inizione viene detto overridin. dee 5unzioni Bsovrapposizione con prevaenza ed e un meccanismo addizionae e diverso rispetto a sovraccarico dea 5unzioni Boveroadin.' 7 primo prevede che nea casse derivata una 5unzione ven.a ride5inita con 5orma identica a ,uea dea casse 0ase e che o..etto dea casse derivata sia appicata a 5unzione ride5inita- in secondo prevede viceversa che due 5unzioni a00iano nome u.uae ma 5irma diversa e che i compiatore sce.a a 5unzione da chiamare sua 0ase de mi.ior adattamento aa 5orma deistruzione chiamata' 7 due meccanismi possono coesistere nee cassi derivate- ne senso che una casse derivata ride5inisce una 5unzione 5B dea casse 0ase due vote- con a medesima 5irmaBoverridin. e con 5irma diversaBoveroadin.' Peratro impie.o dei due meccanismi rischia di compromettere a e..i0iita de codice' Modalita' di derivazione privata
Guida C++: Aspetti Avanzati
<29>
La modaita di derivazione non ha ri5erimento ai diritti di accesso dea casse derivata ae componenti deo..etto di appartenente aa casse 0ase- ma piuttosto aa trasmissione dei diritti di acceso ae componenti dea casse 0ase ae uteriori cassi derivate e ae 5unzioni che utiizzano o..etti dea casse derivata' La modaita di derivazione privata 0occa ereditarieta- ne senso che sia e successive cassi derivate sia e 5unzioni utente non possono accedere ae componenti dea casse 0ase' esempio:
Le 5unzioni mem0ro dea casse derivata possono accedere aa componente privata di 8ase m* soo attraverso e 5unzioni di accesso- se de5inite da pro.ettista dea casse' Ampliamento dei meccanismi di protezione e di derivazione Ao scopo di concedere speci5ici privie.i di accesso ae cassi derivate- i C++ ha ampiato e modaita di protezione e di derivazione- prevedendo otre aa modaita pu00ica e privata- a modaita di protezione e di derivazione protetta' ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<30>
7 mem0ri protetti di una casse 8 sono accessi0ii aa casse derivata ( ma non a.i utenti di 8 o (' La derivazione protetta rende a casse accessi0ie da atre cassi ma non da.i utenti di ,ueste' Per ,uanto attiene ae modaita di derivazione e di protezione si opera tipicamente come: •
a modaita di derivazione viene de5inita pu00ica- ao scopo di consentire a trasmissione dei diritti di accesso ae successive cassi dea .erarchia e a.i utenti9
•
e 5unzioni mem0ro ven.ono de5inite pu00iche- ao scopo di consentire a.i utenti dea .erarchia di derivazione di appicare i metodi richiesti a.i o..etti dea .erarchia9
•
e varia0ii mem0ro ven.ono de5inite protette- ao scopo di consentire accesso aa struttura dati a tutte e cassi dea .erarchia di derivazione ma non a.i utenti'
uesto e in un caso .enerae- ma possono essere ampiate anche con a..iunta di atre accortezze: •
acune 5unzioni mem0ro possono essere dichiarate private se si tratta di 5unzioni di servizio che devono essere utiizzate soo ainterno di una casse9
•
acune 5unzioni mem0ro possono essere dichiarate protette se si tratta di 5unzioni di servizio che devono essere utiizzate soo da 5unzioni mem0ro dee cassi derivate ma non da.i utenti'
esempio:
La casse (erivata eredita da 8ase insieme di 5unzioni mem0ro e di varia0ii mem0ro e accede ai mem0ri pu00ici o protetti di 8ase' Lutente dea casse (erivata accede soo ai mem0ri pu00ici di (erivata e 8ase- ma non ai mem0ri protetti' ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<31>
*unzioni o classi amic"e nella derivazione Ciascuna casse in una .erarchia di derivazione puo de5inire- secondo i consueti meccanismi previsti da in.ua..io- 5unzioni o casse amiche- .arantendo ad esse tutti i diritti di accesso' 7n particoare- una casse 8 puo de5inire amica una 5unzione mem0ro di una casse derivata ( oppure tutta a casse (' 7n ,uesto caso ( ac,uisisce diritti competi di accesso a 8- ma non puo trasmettere tai diritti ae successive cassi dea .erarchi ne a.i utenti' esempio: 6ia 8 a casse 0ase- ( una casse (erivata contenente una 5unzione .B' Ao scopo di consentire a .B di accedere ae componenti private dea casse 8- essa viene de5inita amica di 8: clae H{//clae 2ae della gerarchia friend 4::g(); pu2lic: ... pri?ate: ... }; cla 4:pu2lic H{//clae deri?ata pu2lic: ?oid g();//g() puo9 accedere al otto-oggetto 2ae dell9oggetto proprio ... };
#n esempio di gerarc"ia di derivazione Consideriamo a .erarchia di derivazione di tre cassi: •
La casse P;6>NA- che e a casse piu .enerae dea .erarchia e contiene a struttura dati atta a rappresentare un .enerico individuo e e 5unzioni mem0ro atte a de5inire i comportamento9
•
La casse 6EU(NE- che e una speciaizzazione dea casse 0ase- contiene a struttura speci5ica per rappresentare e in5ormazioni proprie di uno studente e contiene e 5unzioni mem0ro atte a de5inire i comportamento speci5ico di un eemento di ,uea casse9
•
La casse 8>;676EA-che e unuteriore speciaizzazione dea casse studente e contiene atre in5ormazioni speciaizzate reative aa casse stessa- piu speci5iche ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<32>
5unzioni mem0ro che de5iniscono i comportamento' esempio: Casse P;6>NA
Casse 6tudente =111111Achar* 7>="") //lita di iniialiaione che richiama il cotruttore @erona :@erona(5,A,A,)A eami(,')Amatricola(+'7>)A ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<33>
facolta(neB charJtrlen(7>)1K){trcp6(facoltaA7>);} //fine cotruttore tudente //generica funione mem2ro ?oid chiei(){ cout<<"$nono uno tudente di nome"<
Casse 8orsista =111111Achar*7>=""Along H+=1%%%%%%%) //lita di iniailiaione richiama cotruttore tudente :tudente(5,A,A,A,'A+'7>A7>)A 2ora(H+){ }//fine cotruttore Horita //generica funione mem2ro ?oid chiei(){ cout<<"$nono un ?orita di nome"<
(A N>EA; 8N 7 (76E;UEE>;7 N>N 6>N> P;6NE7- "A SNG>N> ;7CH7A"AE7 7"PL7C7EA"NE NLL>;(7N 7NS;6> (LLA G;A;CH7A (7 (;7SAQ7>N: (A 8>;676EA A 6EU(E' Pro.ramma Principae
Guida C++: Aspetti Avanzati
<34>
Horita carlo("Hianchi 7arlo"A1AMAQACP11FCA"'ngegneria"A1E%%%%%); franco.chiei();//richiama @erona::chiei giorgia.chiei();//richiama tudente::chiei carlo.chiei();//richiama Horita::chiei }
Polimorfismo Motivazioni per il polimorfismo 7n una .erarchia di derivazione- acune 5unzioni dea casse 0ase sono ride5inite nee casse derivate' 6e si vuoe con5erire a codice a caratteristica di dinamicita e di adattamento che consenta di richiamare a 5unzione ade.uata a tipo deo..etto per cui essa e invocata' Poimor5ismo sta proprio ad indicare che i so5t2are si ade.ua aa 5orma Btipo deo..etto in cui viene appicato' Ad esempio in una .erarchia di derivazione che comprende a casse 0ase
6i desidera naturamente per ciascun speci5ico o..etto- richiamare a 5unzione dise.naB speciaizzata' A tae scopo percio occorre che sia possi0ie determinare dinamicamente a tempo di esecuzione- a 5unzione dise.naB da ese.uire- in dipendenza de tipo deo..etto a i O' Nea pro.rammazione tradizionae occorre utiizzare in ,uesto caso i costrutto CA6 avente ,uae ar.omento i tipo deo..etto9 nea pro.rammazione ad o..etti ,uesta prestazione viene 5ornita da sistema' 7 poimor5ismo percio nea pro.rammazione ad o..etti mi.iora a dinamicita de sistema' 7 poimor5ismo permette anche di mi.iorare estensi0iita de sistema- perche consente di a..iun.ere una nuova sottocasse- introducendo varianti minime a codice esistente' 7 poimor5ismo viene reaizzato ne C++ attraverso unazione com0inatoria de compiatore e de pro.ramma coe.atore- e consiste ne rinviare a tempo di esecuzione a sceta dea 5unzione da richiamare: in atri termini- i e.ame tra chiamata dea 5unzione e i codice che a impementa e rinviato a tempo di esecuzione BLAE 87N(7NG- e.ame ritardato' Per contrapposizione si usa i termine e.ame anticipato BA;L 87N(7NG ne caso comune in cui a sceta dea 5unzione da richiamare viene compiuta a tempo di compiazione' Meccanismi sintattici per il polimorfismo 6ia 5B una 5unzione de5inita di una casse 0ase dea .erarchia e ride5inita nee cassi derivate9 i C++ consente di de5inire staticamenteBcioe a tempo di compiazione i e.ame ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<35>
tra a 5unzione 5B e o..etto a cui deve essere appicata B0indin. statico- sia di rinviare i e.ame a tempo di esecuzione- ao scopo di ottenere i poimor5ismo' Per esprimere i ate 0indin. i C++ prescrive ,uanto se.ue: •
•
e 5unzioni cui e appica0ie i ate 0indin. devono essere speci5icatamente indicatea tae scopo esse devono essere individuate tramite i ,uai5icatore S7;EUAL e ven.ono di conse.uenza chiamate 5unzioni virtuai9 a chiamata di 5unzione deve assumere una 5orma particoare per esprimere a richiesta di istituire e55ettivamente i e.ame in 5orma ritardata: nea chiamata dea 5unzione 5B o..etto proprio deve essere desi.nato per mezzo di un puntatore Bo di un ri5erimento9
7n sintesi a notazione e: p -! f()
se.ue a chiamata poimor5a di 5B- ne senso che a 5unzione e55ettivamente chiamata e ,uea associata aa casse C cui appartiene o..etto c puntato da p' $ic"iarazioni delle classi della gerarc"ia cla H{ pu2lic: ?irtual ?oid f();//per f puo9 eere eeguito il late 2inding ... }; cla 4:pu2lic H{//4eredita da H pu2lic: ?irtual ?oid f();// f() ?iene ridefinita in 4 };
Ne pro.ramma utente si de5inisce un puntatore aa casse 0ase e a esso viene asse.nato indirizzo di un ,uasiasi o..etto dea .erarchia: per attivare i poimor5ismo si richiama a 5unzione virtuae per mezzo de punatatore: Programma utente della gerarc"ia H*p;//p punta alla clae 2ae 4 d; // d e9 un oggetto della clae deri?ata p=Dd; //p punta a un oggetto della clae deri?ata p-!f(); //legame ritardatoA late 2indingA richiama la funione 4::f() //uo di un arra6 di puntatori H 21A2M; 4 d1AdM; H* ppJCK={D21ADd1AD2MADdM}; for(int i=%;i
Guida C++: Aspetti Avanzati
<36>
//richiama H::f() o 4::f() in relaione al tipo di oggetto puntato ppJ i K-!f(); //late 2inding
*unzioni virtuali pure e classi astratte 7n acuni casi- a 5unzione virtuae e dichiarata ma non de5inita nea casse 0ase B5unzione virtuae PU;A ed e invece de5inita nea cassi derivate' La casse 0ase non ha atro che una 5unzione di inter5accia ma non e possi0ie istanziare o..etti di ,uesta casse Ba casse viene detta casse A6E;AEEA' Per esempio- nea .erarchia Persona B0ase- 6tudente8orsista- a 5unzione chi6eiB dea casse persona puo essere de5inita come virtuae pura e conse.uentemente Persona assume i ruoo di casse astratta: cla @erona{ ... //funione mem2ro ?irtuale pura ?irtual ?oid chiei()=%; };
Le successive cassi dea .erarchia dovranno- in ,uesto caso- de5inire a 5unzione chi6eiB' 7n caso contrario a casse derivata eredita a 5unzione virtuae pura e assume anchessa ruao di casse Astratta' Costruttori e distruttori di classi polimorfe C"iamata di costruttori e distruttori Come .ia visto in precedenza- costruttori e distruttori non ven.ono ereditati- dun,ue ciascuna casse deve provvedere aa oro impementazione' 7 in.ua..io non consente di de5inire costruttori virtuai: a chiamata deve sempre avvenire con 0indin. statico- neordine de5inito daa .erarchia di derivazione- in modo da costruire o..etto a partire daa sua parte 0ase 5ino a pervenire aa parte de5inita neutima casse derivata' Per ,uanto attiene ai distruttori- essi- viceversa- possono B de00ono essere virtuai9 Consideriamo i se.uente schema: 8 casse 0ase • ( casse derivata- con o..etti con estensione dinamica • p tipo puntatore a 8 • ed i 5rammento di pro.ramma: p=neB 4; //itania oggetto di tipo 4A con relati?a parte dinamica .... delete p; //dealloca oggetto p
Loperatore ne2 richiama i costruttore dea casse ( che provvede ad istanziare a parte dinamica9 operatore deete richiama i distruttore per deaocare a parte dinamica' 7 distruttore richiamato viene individuato a mezzo de puntatore p ao..etto da ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<37>
deaocare: ne caso di distruttore non virtuae viene richiamato i ditruttore dea casse 8essendo p di tipo 8M- ne caso de distruttore virtuae viene richiamato ,ueo dea casse ( e successivamen te ,ueo dea casse 8 Bi distruttori ven.ono richiamati a cascata: a partire dautima casse derivata 5ino ad arrivare aa casse 0ase risaendo a .erarchia' 7n concusione in una .erarchia di cassi che presentano piu o..etti con estensioni dinamiche occorre de5inire i reativi distruttori e essi devono essere virtuai' Polimorfismo all'interno dei costruttori e distruttori (ainterno dei costruttori e distruttori possono- in via .enerae- essere richiamate 5unzioni mem0ro dea .erarchia di derivazione9 in ,uesto caso a chiamata viene sempre espressa con e.ame anticipato' 7n atri termini non si puo appicare i poimor5ismo' 7 tutto trova .iusti5icazione ne 5atto che- in caso contrario- a mezzo di una chiamata poimor5a potre00e essere chiamata da un costruttore una 5unzione de5inita nea parte 0asse dea .erarchia- operante su un componente deo..etto non ancora costruito' Struttura della gerarc"ia di classi *unzioni associate alle classi Ao scopo di me.io esaminare e caratteristiche 5unzionai di una .erarchia di derivazione dotata di 5unzioni mem0ro ordinate e virtuai e opportuno introdurre i concetto di N ""8;> A66>C7AEA A UNA CLA66 in una .erarchia di derivazione' Considerando dun,ue una .enerica .erarchia di derivazione- con modaita di derivazione pu00ica' Ciascuna casse a00ia inotre 5unzioni mem0ro pu00iche' (ata una casse C dea .erarchia- consideriamo insieme U costituito daunione di tutte e cassi che apparten.ono ai percorsi che con.iun.ono C con i nodo radice' Possiamo dun,ue ora individuare e 5unzioni mem0ro e e varia0ii mem0ro dea casse C' •
•
varia0ii mem0ro: a casse C ha per varia0ii mem0ro unione dee varia0ii mem0ro dea cassi deinsieme U9 5unzioni mem0ro: a ciascuna casse C sono A66>C7AE e 5unzioni mem0ro deinsieme U'
Lutente dea casse C puo accedere a tutte e 5unzioni mem0ro associate aa casse C- sia che esse siano de5inite ainterno di cassi che precedono C un.o a .erarchia di derivazione' Ne caso di >S;;7(7NG Bcioe di ride5inizione di una 5unzione da parte di una casse derivata- a 5unzione mem0ro ride5inita sostituisce ,uea che precede ai 5ini dea successiva .erarchia di derivazione' Percio con ri5erimento a C possiamo considerare e se.uenti 5unzioni mem0ro: 5unzioni de5inite in cassi che precedono C9 • 5unzioni de5inite nea casse C9 • 5unzioni ride5inite in C Boverriddin.9 • 5unzioni ride5inite in cassi che precedono C9 •
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<38>
Ciascuna 5unzione potra essere- non virtuae- virtuae- o virtuae pura' Accesso alle funzioni membro della gerarc"ia Consideriamo ora e notazioni per accesso ae 5unzioni dea .erarchia di derivazione da parte di un utente dea .erarchia: •
a notazione o'5B da uo.o ad un 0indin. statico e richiede dun,ue che i e.ame con a 5unzione da richiamare sia de5ini0ie a tempo di compiazione9
•
a notazione p!5B e e,uivaente aa o'5B per e 5unzioni non virtuai- ne senso che a 5unzione richiamata viene de5inita da compiatore Ia partireI daa casse > cui punta i puntatore9
•
a notazione p!5B per 5unzioni virtuai da uo.o ad un 0indin. dinamico: a 5unzione richiamata viene de5inita Ia partireI non daa casse > cui punta i puntatore- ma daa casse > primo cui appartiene o..etto puntato da p9
•
e in o.ni caso possi0ie unindicazione espicita dea 5unzione da richiamare a mezzo de nome dea casse con e notazioni: o'V::5B oppure p!V::5B in ,uesto caso i 0indin. e sempre statico indipendentemente daa 5unzione'
7n 0ase ae re.oe de in.ua..io si hanno ancora i se.uenti casi: •
con a notazione o'5B si 5a ri5erimento a una 5unzione de5inita nea casse > oppure a una casse che precede > nea .erarchia di derivazione9
•
con a notazione p!5B si 5a ri5erimento a una 5unzione de5inita nea casse > cui punta p oppure a una casse che se.ue > nea .erarchia di derivazione: in5atti a p puo essere asse.nato indirizzo di un o..etto dea casse > oppure di una casse derivata da >Bup!castin.9
•
con a notazione o'V::5B oppure p!V::5B si puo richiamare una 5unzione de5inita nea casse > oppure in una casse che precede > un.o a .erarchia di derivazione9 ,uestutima eventuaita Bdo2n!castin. e da evitare perche o..etto a cui viene appicata a 5B e Ipiu piccooI deo..etto proprio dea casse V'
e classi notazioni di base nel C++ La casse e un moduo so5t2are con e se.uenti caratteristiche: •
e dotata di uninter5accia Bspeci5ica e di un corpo Bimpementazione9
•
a struttura dati IconcretaI di un o..etto dea casse e .i a.oritmi che ne reaizzano e operazioni sono tenuti nascosti ainterno de moduo che impementa a casse9
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<39>
•
o stato di un o..etto evove unicamento in 0ase ae operazioni ad esso appicate9
•
e operazioni sono utiizzate in modaita che prescindono daaspetto impementativo- in ta modo e possi0ie modi5icare .i a.oritmi senza modi5icare inter5accia'
e classi nel C++ 7 in.ua..io C++ supporta espicitamente a dichiarazione e a de5inizione di tipi astratti da parte deutente mediante i costrutto CLA669 e instanze di una casse ven.ono dette o..etti' 7n una dichiarazione di tipo CLA66 0iso.na speci5icare sia a struttura dati che e operazioni consentite su di essa' Una casse possiede in .enerae una sezione pu00ica ed una privata' La sezione pu00ica contiene tipicamente e operazioni- dette anche metodi- consentite ad un utiizzatore dea casse' sse sono tutte e soo e operazioni che un utente puo ese.uire in maniera espicita od impicita- su.i o..etti' La sezione privata comprende e strutture dati e e operazioni che si vo.iono rendere inaccessi0ii daesterno' esempio: cla 7ontatore { pu2lic : ?oid 'ncrementa(); // operaione incremento ?oid 4ecrementa(); // operaione decremento pri?ate: unigned int ?alue; // ?alore corrente cont unigned int ma8;// ?alore maimo };
Produzione ed uso di una classe 7 meccanismo dee cassi e orientato speci5icatamente aa riusa0iita de so5t2are >ccorre dun,ue 5are ri5erimento ad una situazione di produzione de so5t2are nea ,uae operano: i produttore dea casse i ,uae mette a punto: a speci5ica- in un 5ie di intestazione Bheader 5ie • impementazione dea casse Bun 5ie separato • utiizzatore dea casse- i ,uae ha a disposizione a speci5ica dea casse- crea o..etti e i utiizza ne proprio moduo'
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<40>
%elazioni d'uso tra le classi 7 moduo utente di una data casse puo essere i pro.ramma principae oppure un atra casse' Era e due cassi puo esserci una reazione duso- in cui una svo.e i ruoo di utente dei servizi o55erti daatra' %uolo 2cliente2 6voto daa casse che utiizza e risorse messe a disposizione daatra %uolo 2Servente2 6voto daa casse che mette a disposizione e risorse utiizzate daatra #so di una classe da parte di un modulo utente Un moduo utente dea casse: incude a speci5ica dea casse Bcontenuta ne 5ie nomeCasse'h • de5inisce o..etti istanze dea casse e invoca i metodi su.i o..etti • Istanziazione degli oggetti Un o..etto e unistanza esempare dea casse' (ue esempari dea stessa casse sono distin.ui0ii sotanto per i oro stato- sono i vaori dei dati mem0ro- mentre i comportamento potenziae e identico' #so di una classe a specifica di una classe ;appresenta uninter5accia per a casse stessa in cui sono descritte: e risorse messe a disposizione ai suoi potenziai utenti • e re.oe sintattiche per i oro utiizzo • separata daa impementazione- permette utiizzo senza che .i utenti conoscano i detta.i dea impementazione' a cura deo sviuppatore dea casse' scritta in un apposito 5ie di intestazione' esempio: 6PC7<7CA (LLA CLA66 / / nome del file 7.h cla 7 { pu2lic: //prototipi delle funioni mem2ro ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<41>
1 f1( ....) ; M fM( ....) ; pri?ate: //truttura dati interna int i; char c; } ; //fine pecifica della clae 7.
'implementazione di una classe a codi5ica in C++ dee sin.oe operazioni presentate neinter5accia dea casse' una particoare souzione- perche puo cam0iare impementazione senza che cam0i inter5accia' a cura deo sviuppatore dea casse' scritta in un apposito 5ie di impementazione Bestensione 'cpp esempio: //implementaione della clae //nome del file 7.cpp #include "7.h" 1 7::f1(...){ //realiaione della funione f1 } M 7::fM(...){ //realiaione della funione fM } //fine del file 7.cpp
Struttura degli oggetti Ciascuno o..etti- che e istanza di una casse- e costituito: •
da una parte 0ase- aocata per e55etto dea de5inizione deo..etto ne pro.ramma utente in un area di dati statici- nearea stac% o nearea heap- in 0ase ae cassi di memorizzazione9
•
da una eventuae estensione- aocata in un area heap'
Cico di vita di un o..etto •
de5inizione deo..etto
•
aocazione
•
iniziaizzazione ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<42>
•
deaocazione
de5inizione deo..etto: a cura de pro.ramma utente
aocazione parte 0ase: a cura de compiatore
aocazione eventuae estensione: mediante una speciae 5unzione mem0ro detta C>6E;UEE>; Ba cura percio de produttore dea casse
iniziaizzazione o..etto: a cura de costruttore
deaocazione eventuae estensione: a cura di una speciae 5unzione mem0ro detta (76E;UEE>;
deaocazione parte 0ase: a cura de compiatore
Costruttori 7 costruttore e una 5unzione mem0ro: che ha o stesso nome dea casse • non restituisce nessuno risutatoBnemmeno void • Invocazione dei costruttori >.ni istanziazione di un o..etto dea casse produce invocazione di un costruttore o..etto e creato come varia0ie .o0ae o ocae: ccount act(1%%); o..etto e creato come varia0ie dinamica: ccount *act = neB ccount(1%%); 6e i compiatore non individua i costruttore da chiamare produce un errore' 6e o..etto ha dei dati mem0ro di tipo casse- su ciascuno di essi e chiamato ricorsivamete i costruttore ciascuno dei dati mem0ri sono chaimati secondo ordine di dichiarazione dei dati • a chiamata dei costruttori dei dati mem0ro precede a chiamata de costruttore • deo..etto esempio: Pro.ramma utente dea casse C #include "account.h" main(){ //llocaione di un oggetto ccount act(1%%);//?iene in?ocato il cotruttore ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<43>
//act e9 una ?aria2ile automatica che ?iene allocata nell9area tacR //allocaione dinamica di un oggetto ccount *pact= neB ccount(1%%);//in?oca il cotruttore //il puntatore pact e9 una ?aria2ile automatica allocata in area tacR; //l9oggetto puntato e9 allocato in area heap; }//fine programma utente
$istruttori 7 distruttore e una 5unzione mem0ro che: e necessaria soo se o..etto presenta unestensione dinamica • ha o stesso nome dea casse preceduto da WBtide • non restituisce nessun vaore Bnemmeno void ne ha acun parametro • ha o scopo di deaocare estensione dinamica di un o..etto • non puo essere invocato espicitamente da pro.ramma utete- ma viene invocato • impicitamente da compiatore ,uando termina i cico di vita di un o..etto Invocazione dei distruttori 6e una casse 5ornisce un distruttore- ,uesto e automaticamente chiamatao on.i vota che un o..etto dea casse deve essere deaocato: o..etto e ocae e si esce da 0occo in cui e stato dichiarato • o..etto e neo heap e su di esso viene ese.uito un (LE • o..etto e dato mem0ro di un atro o..etto e ,uestutimo viene deaocato in • ,uesto caso: i distruttori dei dati mem0ri ven.ono invocati neordine di dichiarazione dei dati a chiamata dei distruttori dei dati mem0ri se.uono a chiamata de distruttore deo..etto 6e una casse non 5ornisce un distruttore ne viene creato uno di de5aut che invoca ordinatamente i distruttori di tutti i dati mem0ro' esempio: //programma utenta della clae 7 #include "account.h" ?oid f(){ //llocaione dinamica di un oggetto ccount *pact=neB ccount(1%%); if(...){ ccount act(1%%);//in?oca il cotruttore ... //fine del 2loccoA ?iene in?ocato il ditruttoreA e act ?iene deallocato dall9area tacR } ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<44>
delete pact;//?ieni in?ocato il ditruttore per l9area heap puntata da pact }//fine procedura f
&ipi di costruttori • • •
Con zero ar.omenti Con uno o piu ar.omenti (i copia
esempio: //pecifica della clae //nome del file 7.h cla 7{ pu2lic: //funioni cotruttore 7();//cotruttore a ero argomenti 7(?alori iniiali);//cotruttore con piu9 argomenti 7(cont 7D c1);//cotruttore di copia pri?ate: //truttura dati }//fine della pecifica della clae 7 e funzioni membro I3I30 Le 5unzioni mem0ri inine posso essere de5inite in uno dei se.uenti due modi: usando a paroa chiave inine nea de5inizione dea 5unzione mem0ro • senza a paroa chiave inine ma inserendo i corpo dea 5unzione nea stessa • inter5accia dea casse I dati membro S&A&IC 7 dati mem0ro- pu00ici o privati- di una casse posso essere dichiarati static' 6ono dati creati ed iniziaizzati una soa vota- indipendentemente da numero di o..etti istanziati: vanno dichiarati nea de5inizione dea casse e de5initi ed impementate • separatamente usando operatore di risouzione deo scope- i dati pu00ici- come e normai • varia0ii .o0ai- possono essere usati dovun,ue ne pro.ramma e funzioni membro S&A&IC Le 5unzioni mem0ro- pu00iche o private- di una casse posso essere dichiarate static'
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<45>
6ono 5unzioni che non ricevono ar.omento EH76 e ,uindi: possono accedere soo ai dati mem0ro statici dea casse • possono invocare soo 5unzioni mem0ro statiche dea casse • e funzioni membro C-3S& Le 5unzioni mem0ro che non vanno a modi5icare o..etto devono essere espicitamente dichiarate const' La paroa chiave C>N6E se.ue a ista de.i ar.omenti e deve essere presente sia ne prototipo dea 5unzione mem0ro che nea de5inizione' ,li oggetti C-3S& Lu 5unzioni mem0ro const sono e uniche che possono essere chiamate su un o..etto const Ba parte i costruttori ed i distruttori Il costruttore di C-PIA 7 costruttore di copia di una casse C ha a 5orma: 7(cont 7D)
Siene utiizzato ,uando si deve reaizzare a copia di un o..etto esistente: ne creare un cone di un o..etto • ne passare o..etto per vaore • ne restituire o..etto per vaore • Copia superficiale e copia profonda uando a casse non 5ornisce un costruttore di copia- i compiatore ne crea uno di de5aut che e55ettua a copia super5iciae deo..ettoBIshao2 copTI' Consiste neappicare ordinatamente i costruttore di copia ad o.ni dato mem0ro Bper i dati reativi a copia avviene con operazione sui primi 0Tte reativi uando tra i dati mem0ri deo..etto vi son puntatori- non e opportuno usare a copia super5iciae ma 0ensi una copia pro5onda BIdeep copTI' 7n ,uesto caso i costruttore di copia deve essere espicitamente pro.rammato' Ne caso deo shao2 copT: 7 caratteri di due strin.he sono condivisi BIsharin.I modi5icando i carattere di una strin.a si modi5ica anche atra strin.a • se una dee due strin.he e deaocata- i distruttore deaoca anche arraT di • caratteri- asciando cosi atra strin.a in uno stato scorretto- con un puntatore Idan.in.I'
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<46>
Ne caso de deep copT: >.ni strin.a ha a sua copia di caratteri • ,uaun,ue operazione su una strin.a non modi5ichera atra' • 'operatore di assegnazione Loperatore di asse.nazione di una casse C ha a se.uente 5orma: 7D operator=(cont 7D);
La sua impementazione di55erisce da ,uea de costruttore di copia: deve veri5icare che non si tratti di un autoasse.nazione BFKF • deve distru..ere o..etto vaore attuae dea varia0ie a cui si asse.na • deve restituire i ri5erimento aa varia0ie stessa per permettere catene di • asse.nazione BFKTKz'
Puntatori in C++ 7 C++ prevede puntatori a 5unzioni e puntatori a dati di tutti i tipi- sempici o strutturati' &ipo puntatore un tipo che puo assumere come insieme di vaori tutti .i indirizzi di memoria' Un puntatore ad una varia0ie di tipo E identi5ica indirizzo di memoria dea varia0ie' Percio una varia0ie di tipo puntatore e una varia0ie che contiene indirizzo di memoria dea varia0ie puntata' t6pedef int * pint; pint pcount; //?aria2ile di tipo puntatore int count=1%; pcount=Dcount; // al puntatore ?iene aegnato l9indirio della ?aria2ile count *pint //denota la ?aria2ile puntata da pint (defereniaione)
sempio: int main() { int i=1%; int* p=Di; //@ contiene l9indirio di n *p=M%; return %; }
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<47>
La dimensione de puntatore Bsizeo5B e costante ed e indipendente da tipo puntatonearchitettura a 3* 0it e di 0Tte' Inizializzazione dei Puntatori Un puntatore non iniziaizzato- come ,uasiasi varia0ie- ha come vaore iniziae uno aeatorio B vaore de re.istro di memoria aatto dea sua de5inizione ' imporatente dun,ue iniziaizzare a varia0ie' Un puntatore che viene iniziaizzato a ) Bzero o a NULL non ha nessun vaore- non punta ad nessun o..etto e ,uindi non indirizza a nessun dato presente in memoria ed e detto puntatore nuo' sempio: char *p=%; //oppure char *p=53>>; //i puS tetare il ?alore del puntatore if (p==%) ... //oppure if (p==53>>) Puntatore a puntatore int i=1%%; int *ptr1=Di; int **ptrM=Dptr1
ptr1 e ptr* sono due puntatori diversi' 7 primo X un puntatore ad un intero' 7 secondo- invece- X un puntatore a puntatore' i= QE; *ptr1=QE; **ptrM=QE;
Puntatori costanti Un puntatore costante ha un vaore che non puo essere cam0iato: * cont p=
esempio: int *cont p1=D8;
p1 e un puntatore constante che punta a F- p1 e constante e ,uindi non puo essere modi5icato i suo ri5erimento- ma Mp cioe F e una varia0ie a cui possiamo invece modi5icare i vaore' ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<48>
*p1=1%;// p1=D6;//,+++,
Puntatori a costanti cont * p=
un puntatore ad una varia0ie constante- const' 7 vaore de puntatore si puo modi5icare mentre i vaore puntato no' cont int 8=ME; cont int *p1=D8; *p1= De; //A 0ualun0ue tentati?o di modificare il ?alore di e comportera un errore di compilaione *p1=1E; //,+++,
Puntatori constanti a costanti cont * cont p=
uasiasi tentativo di modi5icare p1 o Mp1 produrra un errore di compiazione' I puntatori -perazioni 7 c++ tratta espicitamente e espressioni di tipo puntatore' 6ono previste e se.uenti operazioni: • • • • •
A66GNAQ7>N: tra puntatori che punatano ao stesso tipo EM: >peratori unari unitari B5orma pre5issa e post5issa 7NC;"NE>: I++I (C;"NE>: I!!I 6>"" (7<<;NQA: tra un puntatore ed un intero
Puntatori a dati strutturati Un puntatore puo puntare a tipo di dati strutturati B arraT o record ' 6i anaizzeranno i se.uenti casi:
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati •
•
<49>
Puntatore ad arraT9 //puY utimente essere sostituito daa notazione a i O tipica de.i arraT Puntatore a record9
Puntatore ad arra4 7 puntatore ad arraT e una varia0ie che punta aa prima ocazione dearraT Ba)O in C+ +9 Considerando pero che .i eementi sono tutti in posizioni conti.ue- i puntatore puntera a tutti .i eemetni dearraT' Un puntatore ad arraT e dun,ue di per se un puntatore costante a tipo E de.i eementi dearraT' sempio: cont int dim=1%%; float a JdimK; // a T un arra6 di dim elementi di tipo float float* p ; // p T un puntatore a float //aeramento di tutti gli elementi di un arra6 di 1%% elementi for (p = aA int i=%; i
Puntatore a record Un puntatore a record e una varia0ie che punta aindirizzo di memoria ove e aocato i record- ,uesto e moto utie nea reaizzazione di tipi dinamici' sempio: // 4ichiaraioni di un tipo trutturato truct { // T un tipo trutturato 41; .....; 4n ; } ; r ; // r T ?aria2ile di tipo // 4ichiaraione di un tipo puntatore a t6pedef * @unt; // 4ichiaraione di ?aria2ile di tipo puntatore a @unt p; @unt p = Dr; // p e9 una ?aria2ile puntatore iniialiata ad r p puo9 eere ridefinito nel coro del programma p= Dr1; //ora p punta alla ?aria2ile r1 di tipo
Accesso aa sin.oa componente: ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<50>
(*p).4i; p-!4i;
sempio: // 4efiniione di tipo truttura: truct 22onati { // definice truttura di nome 22onati tringa nominati?o; tringa indirio; int numel ; }; t6pedef 22onati* @a22; // 4efiniione di ?aria2ili 22onati a; // a una ?aria2ile di tipo 22onati @a22 p= Da; // pA di tipo @a22A e9 iniialiato ad a // cceo alla componente nominati?o mediante puntatore p-!nominati?o;
Classi di memorizzazioni delle variabili in C++ $ic"iarazioni e definizioni imporatante prima di tutto capire a di55erenza tra dichiarazione e de5inizione dee Ientita I di un pro.ramma' Una dichiarazione e una 5rase che introduce un nome in un pro.ramma e ne enuncia e proprieta' Per constani e varia0ii: • !! enuncia i tipo- e casse di imma.azzinamento Per nomi di tipo: • !! introduce i nome e a cate.oria Per 5unzioni • !! prototipo Una de5inizione descrive competamente un entita' Per e varia0ii: • !! dichiara i tipo e de5inisce aocazione in memoria Per nomi di tipo: • !! de5inisci tutti i detta.i de tipo Per e 5unzioni • !! de5inisce i codice dea 5unzione Una de5inizione e anche una dichiarazione' Saria0ii- 5unzioni vanno dichiarate prima di essere utiizzate' Per o.ni entita esistono piu dichiarazioni' ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<51>
Le de5inizioni non possono essere ripetute' Le dichiarazioni devono essere consistenti tra oro e con e de5inizioni' esempi di dichiarazioni: e8tern int a; // dichiara(ma non defin.) la ?aria2le aA definita in altro file. truct @erona; // dichiara un nome di tipo per una truct. ?oid f(int); // dichiara(ma non defin.) la funione f (prototipaione). esempi di de5inizione: cont int 2 = E; // defin. di cotante con nome int a; // defin. di ?aria2ile truct @erona { // definice il tipo @erona char 5omeJM%K; } ; ?oid f(int 8) { // definiione di funione } // corpo della funione Classi di memorizzazione delle variabili nel C++ Per e varia0ii in C++- a de5inizione speci5ica a casse di memorizzazione- cioe: a visi0iita spaziae9 • a durata temporae Bcico di vita9 • aocazione in memoria durante esecuzione' • Cassi di memorizzazione de C++ Bstora.e cass: varia0ii automatiche • varia0ii esterne • varia0ii automatiche statiche • varia0ii esterne statiche • varia0ii re.istrer • varia0ii dinamiche • Modello di gestione della memoria per l'esecuzione di un processo •
•
•
•
Area pro.rammi e costanti destinata a contenere e instruzioni- in in.ua..io macchina- e e costanti de • pro.ramma Area dati statici destinata a contenere varia0ii aocate staticamente e ,uee esterne B.o0ai • Area heap destinata a contenere e varia0ii dinamiche espicite- di dimensioni non • prevedi0ii a tempo di compiazione Area stac% destinata a contenere e varia0ii automatiche ,uee de5inite ainterno dee • 5unzioni
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<52>
1ariabili automatic"e 6ono e varia0ii ocai ad un 0occo di istruzioni' 6ono de5inite in un 0occo di istruzioni e sono aocate e deaocate con esso' La visi0iita essicae e ocae a 0occo' 7n memoria sono aocate nearea stac%' 1ariabili esterne 6ono e varia0ii che ven.ono de5inite aesterno di o.ni 0occo' La visi0iita essicae si estende a tutto i pro.ramma- me per rendere visi0ii anche ae procedure contenute in 5ie diversi- devono essere ivi dichiarate con a paroa chiave eFtern' La oro estensione temporae si estende a tutto i pro.ramma' 7n memoria ven.ono aocate nearea dati statici o .o0ae' 1ariabili automatic"e static"e 6ono varia0ii automatiche pre5issate con a paroe chiave static' La visi0iita essicae e ocae a 0occo di istruzioni dove sono de5inite' La oro estensione temporae si estende a tutto i pro.ramma' 7n memoria ven.ono aocate narea dati .o0ae' 1ariabili esterne static"e 6ono varia0ii esterne pre5issate con a paoa chiave static' La visi0iita essicae e ocae a 5ie dove sono dichiarate' La oro estensione temporae si estende a tutto i pro.ramma' 7n memoria ven.ono aocate narea dati .o0ae' 1ariabili register 6ono varia0ii automatiche pre5issate con a paroa chiave re.ister' La visi0iita essicae e ocae a 0occo dove sono dichiarate' 6ono aocate e deaocate con i 0occo di istruzioni in cui esse sono contenute' 6e possi0ie ven.ono aocate in un re.istro de processore- atrimenti nearea stac%' Puo convenire dichiarare re.ister una varia0ie automatica usata di 5re,uente- in modo che aocazione in un re.istro dea macchina ne aumenti a veocita di accesso' 1ariabili dinamic"e 6ono de5inite durante esecuzione de pro.ramma mediante puntatori' 6ono accessi0ii ovun,ue esiste un ri5erimento ad esse' Laocazione e a deaocazione sono controate da pro.rammatore' ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<53>
7n memoria ven.ono aocate nearea heap' 1ariabili e strutture dinamic"e La .estine dee varia0ii dinamiche e a cura de pro.rammatore- attraverso dei meccanismi un.uistici che sono: • • •
varia0ii di tipo puntatore9 operatore ne29 operatore deete9
-peratore 305 7n 5ase di esecuzione- operatore ne2 aoca unarea atta ad ospitare un vaore di tipo E e restituisce i puntatore a tae area9 7 tipo E de5inisce impicitamete area di memoria occorrente' esempio: * p = neB ; //alloca area atta a contenere un elemento e • retituice puntatore * p1 =neB JnK; //alloca area atta a contenere n elementi e • retituice puntatore -peratore $00&0 Produce a deaocazione dearea di memoria punatata da una varia0ie p- cioe annua aocazione- rendendone di nuovo disponi0ie o spazio de memoria nearea heap' esempio: delete p; //dealloca area puntata da p • delete JK p1; //dealloca tutto l9arra6 precedentemente • allocato delete J1%K p1; //dealloca 1% elementi a partire da 0uello • puntato da p1 Allocazione dinamica di un arra4 Con aocazione dinamica di un arraT i puntatore restituito e ,ueo deindirizzo de primo eemento dearraT' float* a= neB floatJnK;
7 ri5erimento a.i eementi dearraT viene espresso a mezzo dea consueta notazione con indice
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati aJ i K = 1%.%
<54>
*(ai)=1%.%
Allocazione dinamica di un record Laocazione dinamica di un record avviene anao.amente- attraverso uso deoperatore ne2' 7ndicanro con ; un tipo di record e con r un puntatore ad ;- si ha: +* r = neB +;
Allocazione dinamica di un record contenente un puntatore // 4efiniione di tipo truttura: truct 22onati { // definiione del record 22onati char* nominati?o; tringaF% indirio; int numel ;} ; //allocaione dinamica di un record di tipo 22onati 22onati* p = neB 22onati; //legge nominati?o da tatiera char nomeJE%K; cin.get(nomeAE%); p-!nominati?o = neB charJ trlen(nome ) 1 K; trcp6(p-!nominati?oA nome); cout << p-! nominati?o; // deallocaione delete JKp-!nominati?o; //neceario delete p;
Collegamento fra record generati dinamicamente truct 22onati; t6pedef 22onati* @a22; // 4efiniione di tipo truttura: truct 22onati { // definiione del record 22onati char * nominati?o; tringaF% indirio; int numel ; @a22 ucc;//punta al uccei?o record } ; //4efiniione di due ?aria2ili di tipo puntatore ad 22onati @a22 pA p1; //llocaione di due ?aria2ili di tipo 22onati p = neB 22onati; p1= neB 22onati; //7ollegamento del primo record con il econdo p-!ucc=p1;
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<55>
//@er generare dinamicamente piU record collegati a meo di una catena di puntatoriA V ufficiente iniialiare olo il primo recordAcon le itruioni p = neB 22onati; 0 = p; // il ?alore di p non de?e eere alteratoA V la teta della catena ed effettuare 0uindi in ciclo le operaioni 0 -!ucc = neB 22onati 0 = 0-!ucc;//a?ana lungo la truttura
0rrori comuni con puntatori e variabili dinamic"e Eipici errori ,uando si usano varia0ii dinamiche sono: (imenticare di aocare un dato neo heap e usare i puntatore come se o stesse • ri5erendo (imenticare di restituire a memoria utiizzata ao heap mana.er BmemorT ea% • Eentare di usare dati dinamici dopo che sono stati restituiti ao heap mana.er • 7nvocare deete piu di una vota suo stesso dato •
Conversioni di tipo (casting) in C++ Eras5orma in vaore v1 di E1 in un vaore v* di E*' 7 tipi 5ra i ,uai viene ese.uita a conversione- sono in .enerae- tipi che sono uniti tra oro attraverso un percorso di conversione appicato de compiatore' 7 tipo E* di destinazione e noto- in .enerae- sempre a tempo di compiazione' 6i para di: Castin. statico: se anche E1 e noto a tempo di compiazione9 Castin. dinamico: se E1 e noto a tempo di esecuzione9 Le operazione di conversione possono essere espresse in 5orma espicita o appicate impicitamente da processore' 6ono da pre5erirsi e conversoni espicite' >peratori per a conversione di tipo •
tatic&cat<! (8) ! converte F a tipo E- per tipi coe.ati tra oro'
•
reinterpret&cat<! (8) ! converte F ne tipo E- per tipi N>N coe.ati tra oro
•
d6namic&cat<*! (p) ! converte p a tipo EM- per cassi di una .erarchia
•
cont&cat<! (8) ! consente di aterare o..etto costante F di tipo E ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<56>
static6cast 6i utiizza per tipo coe.ato tra oro- a veri5ica e ese.uita a tempo di compiazione' esempio: dou2le =F.1CECC int i= tatic&catN coe.ati tra oro' esempio: char* tr="a2c"; int i= reinterpret&cat
Loperatore in esame e utiizzato in .enere per una conversione di tipo a tempo di esecuzione per i do2n!castin. di puntatori Bda puntatore di una casse 0ase a uno di una casse derivata const6cast 6i utiizza per convertire un o..etto costante in un o..etto non costante' cont&cat<! (8); atera a constness deo..etto costane F di tipo E •
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<57>
Conversione di tipo per oggetti di tipo classe La conversione di tipo per varia0ii di tipo casse e ese.uita nei se.uenti casi: neoperatore di asse.nazione con o..etti di tipo diverso • nea chiamata dee 5unzioni- se parametro e55ettivo e parametro 5ormae sono • scam0iati per vaore e sono di tipo diverso Conversione mediante costruttori Una 5unzione costruttore dea casse V de tipo: W(7D); Puo essere ri.uardata come un operatore di conversione C!V' sse e richiamata impicitamente da compiatore per ese.uire operazione di conversione' 7 tipo C puo essere di tipo standard oppure de5inito dautente' uaora si vo.ia ini0ire utiizzo de costruttore per e operazioni impicite di conversione di tipo 0iso.na premettere attri0uto eFpicit VBC' La conversione di tipo C!V e55ettuata mediante costruttore non e possi0ie: se V e un tipo prede5inito • se V e una casse .ia esistente che non dispone de costruttore VBC • Per tae motivo i C++ introduce .i operatori di conversione: operator VB9//converte o..etto proprio aa casse V • esempio: tringa{ operator int(); }; tringa::operator int(){ //traforma oggetto proprio di tipo tringa in un intero return i; } tringa ("1MF"); int i=; //richiama .operator int();
%idefinizione degli operatori *unzioni operatore 7 C++ consente di de5inire 5unzioni operatore appica0ii a varia0ii di tipo casse' 6i perviene per tae via aa possi0iita di costruire espressioni che utiizzano .i operatori iniziamente de5initi ne in.ua..io come appica0ii ae varia0ii ordinarie di tipo aritmetico o atro tipo prede5inito' 6e.uendo ,uesto approccio possono essere utiizzate espressioni operanti su o..etti:
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<58>
cC= (c1cM)*cF
con c1- c*- c3- c varia0ii di tipo numero compesso' 7n reata- unoperazione su tipo prede5inito- come ad esempio: i1iM //omma di due interi
puo essere ri.uardata come ese.uita a mezzo di richiamo di una 5unzione che ese.ue operazione richiesta- sviuppano un a.oritmo noto a compiatore' La 5unzione somma e inotre ride5inita ne in.ua..io C++ perche e anche prevista a somma di due reai: r1rM //omma di due reali ( ridefiniione della funiona omma)
Loperazione in esame e reaizzata con un a.oritmo diverso- anchesso noto a compiatore' La 5unzione somma puo essere uteriormente ride5inita- con ri5erimento ad operandi appartenenti a una casse C: c1cM //omma di due oggetti della clae 7
Loperazione viene in ,uesto caso ese.uita secondo un a.oritmo de5inito da pro.ettista dea casse C' (a punto di vista tecnico- a redi5inizione di un .enerico operatore >P viene reaizzata mediante de5inizione di una 5unzione di nome operator op' Loccorrenza deoperatore op in unistruzione produce attivazione dea 5unzione operator op in precedenza de5inita' Cosi appicato a 5unzione: c1cM
viene tras5ormata in: c1.operator op(cM)
che produce attivazione dea 5unzione operator opB dea casse C' 6i tratta dea de5inizioni di piu 5unzioni operator opB che costituiscono dun,ue un insieme di 5unzioni di e.ua nome sovraccaricate Boperator overoadin.' 7 compiatorecome per i sovraccarico dei nome- sce.iera a 5unzione che ma..iormente si adatta a tipo de.i operandi' #na tassonomia degli operatori Gi operatori posso essere cassi5icati cosi: •
unari Baccettano un soo operando pre5issiBoperatore precede operando • esempio ne2 e deete • post5issiBoperatore se.ue operando • ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<59>
0inariBaccettano due operandi ad esempio +-! •
•
Acuni operatori possono essere sia unari che 0inari ad esempio M Bdere5erenziazione- motipicazione • Acuni operatori possono essere sia pre5issi che post5issi ad esempio ++ e !! • e regole da seguire Per introdurre un operatore 0iso.na se.uire dee re.oe: e possi0ie modi5icare i si.ni5icato di un operatore esistente- non e possi0ie creare nuovi operatori- non e opportuno cam0iare a semantica di operatori appicati a tipi de5initi9 non e possi0ie cam0iare precedenza- associativita e IaritTIBnumermo di operandi9 non e possi0ie usare ar.omenti di de5aut'
•
• •
Loveroadin. di un operatore puo reaizzarsi un uno dei due modi: come 5unzione mem0ro di una casse un operatore 0inario ha un soo parametro- mentre un operatore unario non ha • parametriBatro operando e o..etto a cui si appica operatore come 5unzione non mem0ro ,uesta souzione e o00i.atoria ,uando a casse non e disponi0ie' •
•
•
Come si comporta il compilatore 7 compiatore ,uando incontra unespressione dea 5orma: 8 op 6
veri5ica neordine: se nea casse V deo..etto F vi e una 5unzione mem0ro dea 5orma operator opB- dove e a casse deo..etto T se vi e una 5unzione non mem0ro dea 5orma Ioperator opBV-I
•
•
e provvede ad invocare a 5unzione individuata' ,li operatori 2sovraccaricabili2 7 C++ consente di ride5inire ,uasi tutti .i operatori previsti de in.ua..io:
-
*
/
X
Y
D
Z ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati [ A = < ! <= -- << !! == = DD = -= *= /= X= Y= D= <<= !!= JK () -! -!* neBJK deleteJK
<60>
!= ZZ Z= neB delete
Non possono essere sovraccaricati: .
.*
::
I:
ieof
Acuni operatori posso essere sovraccaricati soo come 5unzioni mem0ro: = JK () -!
Per atri .i atri se.uiamo a se.uente 5orma: >peratore >peratre unario +K ZK /K MK [K K \K ]K K ^^K >.ni atro operatore 0inario
%idefinizione di operatori specifici >ra andremo a vedere piu neo speci5ico a ride5inizione dei vari operatori: • • • • • • • • • • • •
operatore di asse.nazione9 operatori di incremento e decremento9 operatori di indicizzazione9 operatore 9 operatore vir.oa9 operatore di chiamata di 5unzione9 operatore 9 operatore di shi5t ^^ e 9 operatore !9 operatore O con dimensioni mutipe9 operatori ne2 e deete9 operatori di conversione'
-peratore di assegnazione Prendiamo come esempio una casse C e con c e c1 due o..etti a caso di tae casseoperatore di asse.nazione reaizza operazioni dea 5orma cKc1 ed e dun,ue un operatore 0inario che ha i compito di produrre asse.nazione dee componenti di c1 ae anao.he componenti di c' uesto operatore deve essere ride5inito ne caso in cui .i o..etti si presentano con estensione dinamica- andremo ad operare cosi:
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati •
• • •
<61>
ricopiare a parte 0ase deo..etto c1 nea parte 0ase deo..etto c- a eccezione de puntatore aestensione dinamica9 deaocare estensione di c in area heap9 aocare una nuova estensione di c in area heap9 ricopiare estensione di c1 neestensione di c'
(a punto di vista sintattico i prototipo ha a 5orma: 7D operator=(cont 7D c1);
7 vaore restituito e un ri5erimento ao..etto proprio- e in ,uesto modo ven.ono consentite e asse.nazioni mutipe- nea 5orma c*KcKc1' -peratori di incremento e decremento Loperatore ++ puo assumere come e noto- 5orma pre5issa e post 5issa' Per distin.ure a 5unzione operator ++B nei due casi- i compiatore consente di de5inire due distinte 5unzioni sovrapposte: ++ pre5isso: prototipo 7 operator (); // chiamata c ++ post5isso: prototipo 7 operator (int); //chiamata c 7 compiatore tras5orma a notazione c++ in c'operator++B)' Anao.amente posso essere de5initi .i operatori !! post5issi e pre5issi' -peratori di indicizzazione Un impie.o tipico deoperatore di indicizzazione e ,ueo e.ato aa casse Settore- che prevede accesso a.i eementi di un vettore con controo deindice- ao scopo di veri5icare che esso non sia esterno aintervao o-dim!1O' Ciascun o..etto a di tipo Settore e costituito dae componenti dim- dimensione de vettore- e v- puntatore aarea contenente i vettore' La 5unzione operatorO viene de5inita: D operatorJK(int i){ //controlla i ripetto ai limiti del ?ettore return ?JiK;//retituice riferimento a elemento i-eimo }
La 5unzione in esame e richiamata con notazioni dea 5orma aiO- utiizza0ii sia per accesso ad aiO sia per a..iornamento' uaora occore 5ar ri5erimento a.i eementi di aiO di un vettore costante non e necessario de5inire una seconda 5unzione operatorO' La 5unzione avra prototipo cosi:
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<62>
D operatorJK(int i)cont;
7n atre paroe- ne caso siano de5inite entram0i e 5unzioni- ,uea con o..etto proprio non const verra richiamata per vettori non const e consentira operazioni di a..iornamento,uea con o..etto proprio const verra richiata per vettori const' -peratore 7 Loperatore e un operatore prede5inito per e varia0ii di tipo casse: c 5ornisce indirizzo deo..etto c' Ne caso di o..etto a di tipo Settore operatore puo essere ride5inito- ao scopo di ottenere non indirizzo deo..etto- ma piuttosto indirizzo iniziae dearea v: cont * operatorD()cont{//retituice indirio iniiale del ?ettore return ?; }
-peratore virgola Loperatore vir.oa e- in .enerae- usato per espressioni dea 5orma e-e1 e produce i cacoo di e ed e1 restituendo e1' 6e e ed e1 con .i o..etti c e c1 dea casse C- operatore vir.oa puo essere ride5inito nea 5orma: 7 operatorA(7D c1);
La 5unzione in esame puo essere utiizzata per ese.uire ,uache ea0orazione suo..etto proprio c e su c1 per restituire i vaore c1' -peratore di c"iamata a funzione Loperatore di chiamata 5unzione viene de5inito per cassi che a00iano una soa 5unzione mem0ro: in ,uesto caso si usa anche a denominazione di 5unzione o..etto' 7n atri casi operatore viene de5inito con ri5erimento a una 5unzione mem0ro predominante di una casse' 7 prototipo dea 5unzione operatorB assume a 5orma: + operator()(lita dei parametri);
mentre istruzione di chiamata di ,uesta 5unzione ha a 5orma: c(lita argomenti);
Ne caso in esame o..etto c assume apparenza de nome di una 5unzione9 i numero di ar.omenti dea 5unzione puo assumere ,uasiasi ed e de5inito da pro.ettista dea casse' ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<63>
-peratore 8 Loperatore viene taora de5inito per .estire e condizioni di errore che si producono a se.uito deappicazione di una 5unzione mem0ro 5B- per esempio a 5unzione di in.resso/ uscita' i caso d osservare che ne C++ non e de5inito operatore di vautazione i5Bc- con c di tipo non standard- e in5atti esse rientra tra e operazioni prede5inite per .i o..etti dee casse e non e ride5ini0ie tramite operatore' 7 pro.ettista dea casse puo pero rendere disponi0ie autente anche a notazione i5Bc- attri0uendo opportunamente a essa una semantica compementare a ,uea dea notazione i5Bc' Percio si dovra de5inire un operatore di conversione: operator ?oid*();
La 5unzione esamina .i indicatori di stato e restituisce ) se vi sono errori- atrimenti restituisce i puntatore a c ne caso di non errore' -peratori di s"ift 99 e :: Gi operatori di shi5t ven.ono ride5initi per consentire autente di ese.uire su.i o..etti di una casse C e operazioni standard di in.resso uscita tipiche dee varia0i prede5nite' 7n particoare ven.ono rese disponi0ii autente e operazioni: cin!!c; //legge e memoria le componenti di c cout<
Sen.ono ao scopo de5inite due 5unzioni operatore nea 5orma di 5unzioni ordinaria con due ar.omenti- i primo di tipo istream Boppure ostream- i secondo di tipo C- con i se.uenti prototipi: itreamD operator !! (itreamD inA 7D c); //legge le componenti di c otreamD operator << (otreamD outAcont 7D c); //?iualia c
7n particoare e 5unzioni in esame possono essere dichiarate amiche dea casse C' -peratore .: Loperatore in esame e detto seettore di mem0ro e consente- nea sua de5inizione standard- di puntare a una componente di un o..etto' 7ndicata con C una casse contenente una varia0ie meme0ro pu00ica e- e con c un o..etto di C- si puo accedere aa componente e di c con e notazioni: ...c.el... //accede alla componente el di c 7* p=Dc; //p punta a c ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<64>
p-!el // accede alla componente el di c a meo di puntatore ordinario
Laccesso aa componente e di c puo anche essere ottenuto a mezzo di un ade.uata ride5inizione deoperatore ! ' 7n ,uesto caso si ottiene una ma..iore 5essi0iita perche a 5unzione impicitamente richiamata- puo ese.uire una ,uasiasi atra operazione che i pro.ettista riten.a conveniente de5inire Bda ,ui i termine smart point utiizzato per i puntatori in esame' La ride5inizione deoperatore ! richiede introduzione di una casse ausiiaria PC a ,uae assume i ruoo di casse puntatore aa casse C' La casse PC ese.ue a redi5inizione deoperatore ! - nea 5orma di 5unzione mem0ro- ed e dotata di una varia0ie mem0ro che punta a C' uesto schema aiuta a capire esposto: 6peci5ica dea casse C cla 7{//contiene elemento el pu2lic: //truttura dati pu22lica el; ... };//fine della pecifica di 7
6peci5ica dea casse PC cla @7{//clae auiliariaA redifinice la funione -! pri?ate: 7* pc; //?aria2ile mem2ro di tipo 7* pu2lic: //redifiniione operatore -! 7* operator-!(){... return pc;} @7(7* p):pc(p){} //cotruttoreA aegna a pc il punatatore a 7 }; // fine della pecifica di @7
Uso dea casse C ?oid main(){ 7 c(...);//definice e iniialia oggetto c @7 p(Dc); //richiama cotruttore di @7;pApc puntano a 7 ...p-!el... //richiama p.operator-!() ... }
La notazione p!e consente di accedere aa componente e di c' Piu in .enerae i compiatore ese.ue una chiamata ricorsiva aoparatore unario post5isso ! 5ino a che non si accede a una casse che ha a varia0ie mem0ro di nome e'
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<65>
-peratore ;< con dimensioni multiple Loperatore di indirizzamento O puo essere appicato ripetutamente a un o..ettoo.. etto- purche esso sia opportunamente ride5inito' Ad esempio: oJ i KJ G K
prima viene chiamata a 5unzione: o.operatorJK(i)
6e per ipotesi essa 5ornisce un o..etto c- a tae ar.omento viene ,uindi appicata a 5unzione: c.operatorJK(G)
A00iamo percio o.operatorJK(i).operatorJK(G)
Consideriamo per esempio una casse "atrice con eemti di tipo E- potremo de5inire ainterno di essa una prima 5unzione operatorO con i se.uente prototipo: * operatorJK(int i); //retituice puntatore p alla riga i della matrice.
La 5unzione in esame e richiamata nea 5orma m i O $ O e restituisce un puntatore p aa ri.a i!esima di m' Una seconda 5unzione operatorO puo avere i prototipo: * operatorJK(int G); //retituice puntatore a elemento adi riga i e colonna G
La 5unzione in esame e richiamata nea 5orma p'operatorOB$ e restituisce eemento dea matrice appartenete aa ri.a puntata da p e aa coonna $' -peratori ne! e delete La redi5inizione de.i operatori ne2 e deete per una speci5ica Casse C puo essere e.ata aa possi0iita di appicate a.oritmi di .estione piu e55icienti di ,uei previsti da.i operatori standard- in reazione ae speci5iche esi.enze di aocazione e deaocazione per .i o..etti dea casse C' 7n particoare- utente potra richiamare .i operatori ride5initi- utiizzando e usuai notazioni: 7*p=neB 7; //alloca un oggetto della clae 7 7*p=neB 7JnK //alloca un arra6 di oggetti della clae 7 delete (p); //delalloca oggetto puntato da p ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<66>
deleteJK(p); //dealloca arra6 di oggetti puntati da p
A.i operatori cosi ride5initi si appicano e medesime re.oe viste per .i operatori standard corrispondenti per ,uanto attiene aa chiamata impicita di costruttori e distruttori e aa iniziaizzazione de.i o..etti' Le chiamate in esame ven.ono tradotte da compiatore nee se.uenti 5orme: neB 7 neB 7JnK delete (p) deleteJK(p)
e9 e9 e9 e9
traformato traformato traformato tr traformato
in in in in in
operator neB(ieof 7) operator neB(n*ieof 7) operator delete(p) operatorJK de delete (p (p)
Conse.uentemente i pro.ettista dea casse C dovra utiizzare i se.uenti prototipi di 5unzione: ?oid* operator neB(ie&t n); //alloca un oggeto di n 26te ?oid* operator neBJK(ie&t m); //alloca un oggetto di m 26te ?oid operator delete(?oid* p); //dealloca oggetto ?oid operator deleteJK(?oid*p); //dealloca arra6 di oggetti
7 tipo size_t e un tipo prede5inito- atto ad assumere per vaore a dimensione in 0Tte di un o..etto o di un insieme di o..etti' -peratore di conversione 7n una .enerica casse C possono essere de5inite una o piu 5unzioni per a convenzione di un o..etto c di tipo C in un vaore di tipo V prede5inito o de5inito dautente' La 5unzione di conversione assume necessariamente a 5orma di 5unzione mem0ro dea casse C e ha i se.uente prototipo: operator W(); //con?erte un ?alore di tipo 7 in un ?alore di tipo W
La 5unzione di conversione viene richiamata espicitamente con e notazioni: c.operator W() oppure (W)c oppure tatic&cat
Piu spesso essa e richiamata impicitamente'
Il sistema di I- in C++ 7 C++ e un in.ua..io senza acuna primitiva di 7/>- ma dotato di una i0reria standard che costituisce unestensione de in.ua..io: a i0reria <6E;A"- a ,uae si presenta sotto 5orma di .erarchia di cassi' sse consentono di trattare sia 5ie di tipo testo- con e reative operazioni di 5ormattazionesia 5ie di tipo 0inario' ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<67>
7notre a i0reria introduce i concetto di stream B5usso che rappresenta un astrazione astrazione dei dispositivi di in.resso/uscita- ha o scopo di rendere a scrittura dei pro.rammi indipendente da particoare dispositivo impie.ato- e sempi5icare i pro0ema di porta0iita dei pro.rammi stessi' Lo stream consente di de5inire uninter5accia sempice e uni5orma verso utente' a gerarc"ia di classi I•
• •
7 meccanismo di ereditarieta- 5a si che tutto cio che e possi0ii reaizzare con e cassi IpadriI e anche possi0ii reaizzare sue cassi derivate9 Lheader 5ie iostream contiene e cassi ios-istream-ostream-iostream: Lheadre 5ie 5stream incude iostream- e contiene inotre e cassi i5streamo5stream- 5stream'
7notre ci sono atre cassi- ,uai a casse 6E;A"8U<- che .estisce i 0u55er di 7/> ed ese.ue e operazioni di accesso ae unita 5isiche de sistema' Uteriori cassi sono e cassi 76E;6E;A"- >6E;6E;A" e 6E;6E;A" per e operazioni di etture scrittura su strin.he- invece che su 5ie' e classi istream e ostream Le cassi 5ondamentai per e operazione di 7/> primarie sono: • •
istream- per e operazioni di input9 ostream- per e operazioni di output9
6i tratta di due cassi predisposte per e operazioni di 7/> se,uenziai su 5ie di tipo testoparticoarmente adatte per 7/> primario Btastiera-video-stampante' 7n un pro.ramma percio ven.ono introdotte speci5iche varia0ii su cui operare: itream a; otream 2;
introducono varia0ii a di tipo istream e 0 di tipo ostream' Le varia0ii di tipo ostream e istream sono varia0ii strutturate che contenono tutte e in5ormazioni occorrenti per a .estione deo stream: • • • • •
sui 0u55er associati ao stream9 sue dimensioni deo stream9 su.i errori9 sua posizione corrente dei puntatori ao stream9 su I5ine 5ieI
,li stream standard cin e cout Le operazioni di 7/> primarie avven.ono in particoare a mezzo di due varia0ii standard: ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati • •
<68>
C7N- di tipo istream- che rappresenta a tastiera9 C>UE- di tipo ostream- che rappresenta i video9
tai varia0ii- aatto di esecuzioni di ciascun pro.ramma- risutano prede5inite e i 5ie corrispondenti risutano aperti' Acuni esempi: Lettura di un carattere CH Bcompreso o spazio cin.get(ch); int i=cinAget();
Lettura di una strin.a char J1%%K; cin.get(A1%%);//il carattere 9$n9 reta nello treamA non e9 conumato char J1%%K; cin.getline(A1%%);//il carattere 9$n9 ?iene prele?ato ed eliminatoA ena immetterlo in
Atre 5unzioni di ostream otreamD put(char c); otremD Brite(char *A int n);
esempio: char ch=9a9; cout.put(ch); char J1%%%K; cout.Brite();
-perazioni di ingresso e uscita con formato *unzioni per il controllo del formato 7 controo de 5ormato avviene a mezzo di opportune 5unzioni mem0ro dea casse ios: •
int 2idthBint : de5inisce ampiezza de campo9
•
int 2idthB : de5inisce ampiezza de campo9
•
int precisionBint : de5inisce a precisione per i numeri reai9
•
int precisionB : restituisce a precisione precedentemente de5inita9 ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<69>
esempio: cout.Bidth(C); cout<<9a9; cout<
Manipolatori senza argomento #so dei manipolatori senza argomento Nea i0reria iostream sono de5initi numerosi meccanismi per ese.uire operazioni suo stream- detti manipoatori' Acuni manipoatori sono privi di ar.omento: •
5ush : svuota i 0u55er di uscita
•
end : invia a cout i carattere n
•
ends : invia a cout i carattere )
•
dec : de5inisce 0ase decimae per .i interi
•
heF : de5inisce 0ase esadecimae per .i interi
•
oct : de5inisce 0ase ottae per .i interi
•
2s : produce eiminazione spazi senza input
6ono utiizzati nea 5orma .enerae: cout<
esempio: cout<
Manipolatori con un argomento #so dei manipolatori con un argomento Uteriori manipoatori con un ar.omento sono de5initi ne 5ie iomanip : ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
•
set0aseBint : posizione 0ase per interi
•
setprecisionBint : 5issa precisione per reai
•
set2Bint : 5issa ampiezza de campo
•
setios5a.Bon. : posiziona a 1 i 5a. di 5ormato
•
resetios5a.Bint : posiziona a ) i 5a. di 5ormato
<70>
7 manipoatori eencati sono utiizzati nea 5orma .enerae: cout<
esempio: cout.etpreciion(1%);//produce la definiione di una preciione pari a 1% ed e9 e0ui?alente a cout.preciion(1%)
,estione dello stato dello stream Lo stato deo stream e rappresentato da un insieme di indicatori deo stado deo stream a vaori )- 1 oppure 5aso- vero' 7 0it in esame sono memorizzati in una varia0ie mem0ro dea casse ios di nome state e tipo intero- in posizione opportuna' 7n particoare .i indicatori re.istrano a condizione veri5icatasi a se.uito deesecuzione deutima operazione in.resso/uscita sono de5initi cosi: •
eo50it : assume vaore vero ne caso di 5ine 5ie9
•
5ai0it : assume vaore vero ne caso di un errore di 5ormato che non ha prodotto a perdita di caratteriBerrore recupera0ie9
•
•
0ad0it : assume vaore vero ne caso di un errore che ha comportato a perdita di dati Berrore irrecupera0ie9 .ood0it : assume vaore vero ne caso in cui non vi sia un errore Beo50it-5ai0it-0ad0it sono posizionati a )
7notre e de5inita a 5unzione mem0ro: ?oid clear(int i=%);
Utiizzata per posizionare a .ood o stato deo stream- ao scopo di procedere aoperazione di 7/> dopo un errore' d ancora o stato deo stream puo essere esaminato a mezzo di una 5unzione mem0ro ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<71>
int rdtate()cont;
La ,uae restituisce un vaore intero che codi5ica i vaori di eo50it- 5ai0it- 0ad0it' esempio: //eta il ?alore di good2it 2ool.good()cont; cin.good(); //eta il ?alore di eof2it 2ool eof() cont; cin.eof(); //eta il ?alore di fail2it 2ool.fail()cont; cin.fail(); //eta il ?alore di 2ad2it 2ool.2ad() cont; cin.2ad(); //inoltre ?oid clear (int i=%); int rdtate() cont;
-perazioni di I- verso le memorie di massa Le operazione di 7/> per 5ie ,uasiasi costituiscono una .eneraizzazione di ,uee primarie9 occorre a..iun.ere: • • • •
aperture de 5ie o..etto deoperazione e ,uindi a sua caratterizzazione9 o sviuppo dee operazioni per 5ie 0inari9 e operazioni reative ai 5ie di accesso diretto9 i trattamento di eventuai errori'
La i0reria 7/> de C++ mette disposizione tre cassi: •
i5stream : per input9
•
o5stream : per output9
•
5stream : per operazioni di a..iornamento'
Le cassi i5stream e o5stream sono derivate di istream e ostream e a..iun.ono ae operazioni da esse de5inite anche e operazioni su 5ie ad accesso diretto' Apertura di un file ;ichiede un coe.amento tra unita 5isica in o..etto deoperazione e a varia0ie di tipo ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<72>
stream de5inita ne pro.ramma' (ue distinti 5ormaismi che coincidono pero nea semantica: ! Attraverso un costruttore: < tipofile ! nome'nterno(nome,ternoJA< pecificatori !K); ! Attraverso a 5unzione open: < tipofile ! nome'nterno; nome'nterno.open(nome,ternoJA< pecificatori !K); C"iusura di un file compementare a ,uea di apertura e pone tramite a coe.amento tra a varia0ie di tipo 5ie de5inita ne pro.ramma e i 5ie disponi0ie sue memorie di massa' ! Attraverso a 5unzione cose: < tipofile ! nome'nterno; nome'nterno.cloe(); Specifica delle operazioni da compiere Era .i speci5icatori deoperazione di apertura e incuso i parametro mode- attraverso i ,uae si de5iniscono e caratteristiche de 5ie:
•
//in5ormazioni reative aa struttura interna de 5ie ios::0inarT ! apertura in modaita 0inaria Btesto per de5aut9
•
//in5ormazioni reative a tipo di operazioni su 5ie ios::in ! apertura in input9
•
ios::out ! apertura di output- con sovrascrittura9
•
ios::in \ ios::out ! apertura di input e output9
•
ios::app ! apertura di output con append9
•
ios::ate ! dopo open si sposta a 5ine 5ie9
•
//in5ormazioni reative aa creazione ios::norepace ! in scrittura apre un 5ie nuovo9
•
ios::nocreate ! in scrittura non crea i 5ie se non esiste9
•
ios::trunc ! se i 5ie esiste cancea i contenuti'
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<73>
%egole di default • • • • • •
per de5aut apertura e in modaita testo9 in input- se i 5ie non esiste apertura da errore9 in output- se i 5ie non esiste viene creato- se esiste viene canceato e sovrascritto9 per i5stream e ios::in9 per o5stream e ios::out9 per 5stream non vi e de5aut- i modo va espicato'
Apertura per sola scrittua Loperazione di apertura per soa scrittura e deicata perche puo produrre a canceazione indesiderata di un 5ie esistete- percio si puo operare come se.ue: • • • •
se i 5ie da aprire e un 5ie nuovo si usa ios::norepace9 se i 5ie deve essere scritto soo in append- si usa ios::out \ ios::app9 se i 5ie da aprire puo essere canceato si usa a modaita ios::out9 se i 5ie da aprire e un 5ie .ia esistente che deve essere a..iornato- si usa a modaita ios::in \ ios::out'
esempi: //aprire un file eterno1 con nome interno f1 iftream f1("eterno1"); //apre in output il file eterno1 con nome file interno fM oftream fM ("eternoM"); //apre in aggiornamento il file eternoF con nome fF ftream fF("eternoF"A io::inZio::out); //apertura in input con open iftream f1; f1.open("eterno1"); //apertura in output di un file eitenteA mod. append oftream fF; fF.open("file.out"Aio::outZio::app); //apertura in aggiornamento di un file eitente ftream fC("file"Aio::inZio::out); //crittura di un 2locco di 26te in modalita9 2inaria oftream o; o.open("eterno"Aio::2inar6); float ?J1%%%K; int n= 1%%%*ieof(float); //cri?e n 26te u o prele?andoli da ? o.Brite(reinterpret&cat< unigned char*!(?)An); .... //lettura di un 2locco di 26te in modalita9 2inaria iftream i; i.open("eterno"Aio::2inar6); float ?J1%%%K; int n=1%%%*ieof(float); ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<74>
//legge n 26te da i e li pone in ? i.read(reinterpret&cat< unigned char*!(?)An);
-perazione per file ad accesso diretto a .estione dei 5ie con accesso diretto avviene a mezzo dee 5unzioni di posizionamento e interro.azione sua posizione' 6ui 5ie ad accesso diretto tipicamete di opera in a..iornamento- aternando ,uindi operazione di ettura con operazioni di scrittura' Per motivi di 0u55erizzazione tra operazione di scrittura e ,uea di ettura deve essere interposta unoperazione di posizionamento' • • • •
istream see%.Bon. p : Posizionamento per ettura9 ostream see%pBon. p : Posizionamento per scrittura9 on. te.B :
esempi: //peraioni per file ad acceo diretto ftream f("eterno"Aio::2inar6 Zio::inZio::out); //definice truttura del record truct +ecord{ ..... }; +ecord r; int n=ieof(+ecord); long po=M%%%; ... long g=f.tellg(); ... long p=f.tellp(); f.eeRp(po*n); f.Brite(reinterpret&cat
ostream 5ushB : 6vuota o stream9 int pee%B : Copia i carattere succ' deao stream senza estraro9 istream put0ac%Bchar c : ;ipone i carattere c neo stream9 istream i.nore Bint nK1-int deimK>< : 7.nora n caratteri9 void eat2hiteB : strae spazi consecutivi9 int .countB :
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<75>
Strutture dati astratte • • • •
Lista Pia Coda Ea0ea
A$& ista Lista ordinata/non ordinata Poitica di accesso a.i eementi ;eaizzazione ArraT • Lista dinamica a puntatori • %appresentazione con arra4 6truttura dati: ArraT statico piu eventuamente una varia0ie di tipo intero che mantiene i numero corrente de.i eementi nea ista ed inotre varia0ii che rappresentano indici suarraT' La se,uenza de.i eementi e data daa posizione stessa de.i eementi dearraT' Lista non ordinata: 7niziaizzazione BneemK) 7nserimento in testa Bpush 7nserimento in coda ;icerca se,uenziae iminazione in testa Bpop iminazione di un eemento dato Anaisi deeemento in testa Btop Cacoo dei predicati emptT/5u BneemKK)9neemKKN Lista ordinata: Le operazioni devono .arantire ordinamento La .estione e onerosa perche richiede o spostamento 5isico de.i eementi in caso di inserimento e di eiminazione %appresentazione con lista dinamica a puntatori 6truttura dati ;ichiede a dichiarazione di un tipo ;ecord ./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<76>
costituita da un puntatore a tipo ;ecord che rappresenta a testa dea ista Gi eementi dea ista ven.ono aocati dinamicamente Lista non ordinata 7niziaizzazione B7K) 7nserimento in testa Bpush 7nserimento in coda ;icerca se,uenziae iminazione in testa Bpop iminazione di un eemento dato Anaisi deeemento in testa Btop Cacoo dei predicati emptT/5u B7KK)/: Last in
A$& Coda
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati
<77>
Coda con poitica di .estione <7<>:
Lincremento de.i indici puntatori e e55ettuato da moduo N %appresentazione degli A$& Pila e Coda con lista dinamica a puntatori de tutto simie a ,uanto .ia visto La struttura dati dea Pia prevede un puntatore aa testa' La struttura dati dea Coda prevede un puntatore aa testa ed uno aa coda- cosi da 5aciitare acune operazioni- ad esempio inserimento in codaBsenza scorrere tutta a struttura A$& &abella Una ta0ea e una struttura dati de5inita come un insieme 5inito di coppie: 7=(8A6)
8 appartiene WA 6 appartiene \
do?e 6=f(8)
F e detta chiave dea ta0ea9 7 tipi V e possono essere tipi sempici o strutturati' ;appresentazione •
7n 5orma statica mediante arraT
./Giuseppe_N3mes1s
Guida C++: Aspetti Avanzati •
<78>
7n 5orma dinamica mediante ista a puntatori
Le coppie possono essere ordinate per chiave oppure non ordinate per chiave %appresentazione statica con arra4 di record 7 record rappresenta a coppia chiave!in5ormazione Un unico arraT monodimensionae i cui eementi sono i record %appresentazione con matrice Un unico arraT 0idimensionae La prima coonna contiene e chiavi La seconda coonna i vaori corrispondenti ae chiavi Limitazione 5orte: e chiavi e e in5ormazioni devono essere deo stesso tipo %appresentazione statica con due arra4 monodimensionali (ue arraT monodimensionai 7 primo contiene e chiavi 7 secondo contiene i vaori corrispondenti ae chiavi %appresentazione mediante lista dinamica Ciascun eemento dea ista e un record contenente tre campi: chiave- in5ormazionepuntatore a prossimo'
./Giuseppe_N3mes1s