Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>IMPARARE</strong> <strong>IL</strong><br />
<strong>C++</strong> <strong>in</strong> 2 <strong>ore</strong> e mezzo<br />
Modulo-1<br />
Roberto Sant<strong>in</strong>elli-Perugia
Outl<strong>in</strong>e Modulo1<br />
• Introduzione OO-<strong>C++</strong>.Perché<br />
• Gett<strong>in</strong>g started<br />
• Variabili&costanti<br />
• Statements e blocchi: if <strong>in</strong> <strong>C++</strong><br />
• Funzioni<br />
• Classi e oggetti<br />
• Loop<strong>in</strong>g<br />
• Puntatori
I punti dell’object oriencted<br />
Mentre all’<strong>in</strong>izio I programmi dovevano<br />
fare meno cose (calcolo e maneggio di<br />
raw data) erano semplici ,gli utenti<br />
dovevano essere esperti di computer.<br />
OGGI I programmi sono facili da usare<br />
ma nel loro cu<strong>ore</strong> racchiudono una<br />
grande complessita’
• L<strong>in</strong>guaggio compilato (=velocità) e non <strong>in</strong>terpretato (si può runnare<br />
l’eseguibile anche su macch<strong>in</strong>e che non hanno il sorgente e il<br />
compilat<strong>ore</strong>)<br />
• Facilità di sviluppi successivi <strong>in</strong> base alle esigenze future<br />
(capacita’ di isolare la parte di programma da modificare).<br />
• Divide et impera(=tante componenti,una per ogni azione che si<br />
deve svolgere per risolvere un problema complesso)<br />
• Possibilità di usare questi “oggetti” anche <strong>in</strong> altri applicativi(tipico<br />
di OO e non di altri l<strong>in</strong>guaggi es.Un programma <strong>C++</strong> può chiamare<br />
delle classi Java o delle <strong>in</strong>terfaccia a DB Oracle)<br />
• Event-driven(=maggi<strong>ore</strong> <strong>in</strong>terazione utente programma non piu’ un<br />
flusso predef<strong>in</strong>ito ma possibilita’ di scegliere come far andare le<br />
cose tramite f<strong>in</strong>estre e pulsanti…)<br />
OO cerca di soddisfare tutte queste richieste provvedendo tecniche<br />
per maneggiare le enormi complessita’dei problemi odierni.<br />
In l<strong>in</strong>ea di pr<strong>in</strong>cipio trattando dati e le procedure che agiscono sopra I<br />
dati stessi come un unico s<strong>in</strong>golo oggetto, autocontenuto e con<br />
sue caratteristiche proprie e “adattabili” alle esigenze del momento.
I 4 pilastri di un l<strong>in</strong>guaggio OO<br />
• Encapsulation<br />
• Data Hid<strong>in</strong>g<br />
• Inheritance<br />
• Polymorphism
Encapsulation<br />
Un <strong>in</strong>gegnere che necessità nel suo<br />
progetto un resist<strong>ore</strong> non lo costruisce da<br />
zero ma semplicemente lo usa.Quello che<br />
lui userà sarà un oggetto assolutamente<br />
ben def<strong>in</strong>ito, di cui conosce le<br />
caratteristiche e i risultati di una sua<br />
implementazione, ma creato da<br />
qualcunaltro
Data-Hid<strong>in</strong>g<br />
‣ Con l’encapsulation si effettua anche una data<br />
hid<strong>in</strong>g:l’<strong>in</strong>gegnere necessita delle caratteristiche<br />
esterne del resist<strong>ore</strong> ma non di come lavora al<br />
suo <strong>in</strong>terno (una black box), né delle proprietà<br />
<strong>in</strong>tr<strong>in</strong>seche che appunto sono <strong>in</strong>capsulate nell’<br />
oggetto resist<strong>ore</strong>.Bisogna solo saper usare<br />
questo oggetto <strong>in</strong> base alle nostre necessità.<br />
‣ In <strong>C++</strong> encapsulation e data-hid<strong>in</strong>g sono<br />
r<strong>in</strong>chiuse <strong>in</strong> un oggetto chiamato classe
Inheritance(derivazione)<br />
Se vuoi una BMW530 con 7 marce anziché 5 con<br />
turbo <strong>in</strong>tercooler, nella realtà l’<strong>in</strong>gegnere di<br />
Monaco non progetta da zero una nuova BMW<br />
ma prende “spunto” dal modello circolante e<br />
aggiunge le nuove caratteristiche.<br />
Il nuovo oggetto (classe) sarà qu<strong>in</strong>di adatto alle<br />
nuove esigenze (problemi) anche se non avrà<br />
richiesto una mole di lavoro come per crearlo<br />
ex-novo ma semplicemente sarà una estensione<br />
di qualcosa di preesistente da cui erediterà le<br />
caratteristiche usate f<strong>in</strong>o a quel momento<br />
allargandole.
Polymorphism<br />
Una classe che è derivata da un’altra viene<br />
utilizzata allo stesso modo (es.monto <strong>in</strong><br />
macch<strong>in</strong>a, giro la chiave,<strong>in</strong>grano la marcia<br />
accelero) ma porta a risultati differenti.<br />
(6sec100Kmh contro i 10!)<br />
Polimorfismo <strong>in</strong>dica quella proprietà che uno<br />
stesso oggetto con uno stesso nome<br />
(es.BMW530) può avere associate più forme e<br />
qu<strong>in</strong>di conseguenze differenti nello stesso<br />
utilizzo delle sue differenti manifestazioni.
Gett<strong>in</strong>g started
Gett<strong>in</strong>g started<br />
1.#<strong>in</strong>clude <br />
2.<strong>in</strong>t ma<strong>in</strong>()<br />
3.{<br />
4. Cout
Le parti del programma<br />
Un programma <strong>in</strong> <strong>C++</strong> consiste di di variabili,funzioni, classi, ed altri<br />
enti che scopriremo di volta <strong>in</strong> volta.<br />
Ogni volta che si compila un programma entra <strong>in</strong> funzione anche un<br />
preprocess<strong>ore</strong> che guarda nelle l<strong>in</strong>ee del tuo codice a cercare un<br />
simbolo (#) agendo su queste l<strong>in</strong>ee prima del compilat<strong>ore</strong>.<br />
L’istruzione <strong>in</strong>clude dice al preprocess<strong>ore</strong> di fare quello che c’e’ nelle<br />
l<strong>in</strong>ee di codice del file fra .<br />
Ogni programma <strong>in</strong>izia con una ma<strong>in</strong>() che e’ una speciale funzione <strong>in</strong><br />
quanto non chiamata da altre funzioni ma sempre presente.<br />
Funzione =blocco di codice che fa delle azioni delimitato da parentesi<br />
grafe e che deve essere sempre dichiarata nel tipo <strong>in</strong> uscita e nelle<br />
variabili <strong>in</strong> <strong>in</strong>gresso (es.<strong>in</strong>t ma<strong>in</strong>( ) ritorna un <strong>in</strong>tero)<br />
Cout e’ un oggetto usato d’abitud<strong>in</strong>e per pr<strong>in</strong>tare nello schermo<br />
str<strong>in</strong>ghe fra “ “Alla f<strong>in</strong>e ci sono piu’ opzioni
Uso di cout ,di c<strong>in</strong> e dei commenti<br />
cout
Un esempio più complesso<br />
#<strong>in</strong>clude <br />
<strong>in</strong>t Add(<strong>in</strong>t x , <strong>in</strong>t y)<br />
{<br />
cout
Variabili e costanti
Variabili e costanti<br />
I programmi maneggiano dati che sono storati<br />
sotto forma di variabili e costanti.<br />
Una variabile e’ la label di una una locazione di<br />
memoria <strong>in</strong> cui storare un val<strong>ore</strong> senza<br />
conoscerne l’<strong>in</strong>dirizzo dello spazio riservato<br />
(pensa alla rubrica di un cellulare…)<br />
A seconda del tipo con cui dichiari una variabile il<br />
compilat<strong>ore</strong> associa lo spazio di memoria a<br />
quella data variabile.<br />
Sizeof() e’ una funzione del compilat<strong>ore</strong> che ti dice<br />
quanti bytes sono associati ad un tipo di
Tipi di variabili<br />
*buona cosa:dare dei nomi concernenti il tuo<br />
problema (evita pippo, a, b,x,y se puoi!)<br />
short <strong>in</strong>t numEvent;<br />
float transvMoment;<br />
long <strong>in</strong>t totNumbOfTrack;<br />
char histoName;<br />
double pseudoRapidity;<br />
Inoltre si puo’ dichiarare un <strong>in</strong>tero (corto o lungo)<br />
pure unsigned (solo positivo 0-65535) o signed<br />
(anche negativo da –32768 a +32767).
Dichiarazione di variabili<br />
Piu’ modi per dichiarare e associare un val<strong>ore</strong> ad<br />
una variabile:<br />
1.unsigned short <strong>in</strong>t lunghezza;<br />
unsigned short <strong>in</strong>t larghezza;<br />
lunghezza=5;<br />
larghezza=7;<br />
2.unsigned short <strong>in</strong>t lunghezza=5,larghezza=7;<br />
O addirittura:<br />
3. typedef unsigned short <strong>in</strong>t USHORT;<br />
USHORT lunghezza=5,larghezza=7;
Costanti <strong>in</strong> <strong>C++</strong><br />
Come le variabili le costanti sono locazioni di memoria<br />
dove storare dati ma NON cambiano.<br />
Ci sono due tipi di costanti:letterali e simboliche<br />
Letterale:<br />
e’ un val<strong>ore</strong> che digiti nel tuo programma quando e’<br />
necessario<br />
(es <strong>in</strong>t myAge=28; //28 e’ una costante letterale)<br />
Simbolica:<br />
StudentiPerClasse=15;<br />
StudentiLiceo=classi*StudentiPerClasse<br />
(serve solo a rendere piu’ comprensibile il codice)
Def<strong>in</strong>izione delle costanti<br />
(vecchio metodo con il preprocess<strong>ore</strong>)<br />
#def<strong>in</strong>e StudentiPerClasse 15<br />
(miglior metodo)<br />
const unsigned short <strong>in</strong>t StudentiPerClass=15;<br />
(costanti enumerate)<br />
Puoi creare nuovi tipi di costanti per agganciarti alla realta’<br />
enum Color {RED,BLUE,GREEN,WHITE
Esempio<br />
Int ma<strong>in</strong>();<br />
{<br />
enum Days{ Sunday,MonDay,Tuesday,Wednesday,Thursday,Friday,Saturday};<br />
/* Domenica=0,Lunedi=1……………….,Sabato=6*/<br />
Days Dayoff; //dichiara Dayoff una costante del tipo Days<br />
<strong>in</strong>t x;<br />
cout
Statements e blocchi di<br />
statement
Statements e Blocchi<br />
Uno statement controlla la sequenza di esecuzione,valuta<br />
una espressione o non fa nulla (null statement).TUTTI<br />
gli statement f<strong>in</strong>iscono con il “ ; ”.<br />
x=a+b; //assegna a x la somma di a e b<br />
Un blocco (compound of statements) e’ un <strong>in</strong>sieme di<br />
statements eseguiti <strong>in</strong> cascata che funzionano come un<br />
unico statement e sono delimitati da { }<br />
{<br />
temp=a;<br />
a=b; //swappa I valori delle varialbili a e b<br />
b=temp;<br />
} //non c’e la semicolonna!
Operatori-regole di base.<br />
Assegnamento :x=10.0; (=)<br />
Incremento : c=c+1; oppure c++;(++)<br />
Decremento:c=c-1; oppure c--;(--)<br />
** <strong>in</strong>t a=++x; (assegna ad a il val<strong>ore</strong> <strong>in</strong>crementato<br />
di x)<br />
<strong>in</strong>t b=x++ (assegna a b il val<strong>ore</strong> di x e poi<br />
<strong>in</strong>crementa x)<br />
Stesse regole di precedenza che siete soliti con il<br />
fortran che possono essere stravolte dall’uso di<br />
parentesi.
Operatori relazionali<br />
1.0=falso<br />
2.Tutto il resto =vero<br />
3.== compara due variabili (o<br />
costante/variabile)<br />
4.>,>=,
Blocco if<br />
S<strong>in</strong>tassi<br />
If(expression) statement; se l’espressione e’ vera esegue altrimenti<br />
Oppure va al next statement<br />
If(expression)<br />
{<br />
statements;<br />
}<br />
Uso di else<br />
if(expression) statement;<br />
else statements;
If concatenati<br />
If (expression1)<br />
{<br />
if(expression2) <strong>in</strong>dentatura come gli spazi e’<br />
statement1;<br />
<strong>in</strong><strong>in</strong>fluente (solo stile) <strong>in</strong> <strong>C++</strong><br />
else<br />
Da sottol<strong>in</strong>eare solo l’uso delle parentesi<br />
{ a <strong>in</strong>dicarci chi e’ l’else di quale if…..<br />
if(expression3)<br />
statement2;<br />
else<br />
AND&&<br />
statement3; OR | |<br />
} NOT !<br />
}<br />
else<br />
statement4;
Ancora sull’if statement<br />
Operat<strong>ore</strong> Condizionale (ternario) (:)<br />
E’ l’unico operat<strong>ore</strong> a prendere tre term<strong>in</strong>i<br />
(expression1) (expression2) : (expression3)<br />
Se l’espressione 1 e’ vera ritorna l’espressione 2 altrimenti<br />
l’espressione 3<br />
Un esempio:<br />
Z=(x>y) X:Y<br />
** In <strong>C++</strong> 0 e’ falso e non e’ raro vedere espressioni tipo<br />
If(x) x=0; che serve per azzerare variabili<br />
(leggi come:se x non e’ nullo setta il val<strong>ore</strong> zero)
Funzioni
Funzioni<br />
E’ a tutti gli effetti un sottoprogramma che agisce su dati e<br />
tira fuori un val<strong>ore</strong>.<br />
Ogni programma ha almeno una funzione che e’ ma<strong>in</strong>(<br />
).Ogni funzione puo’ chiamarne altre purche’ dichiarate<br />
prima.<br />
Ogni volta che si <strong>in</strong>contra il nome della funzione il flusso<br />
del programma entra nlla funzione per poi riprendere<br />
dalla l<strong>in</strong>ea successiva.<br />
Per dichiarare una funzione ci sono due modi:<br />
o Scrivi il tuo prototipo <strong>in</strong> un file e qu<strong>in</strong>di usi #<strong>in</strong>clude<br />
o Scrivi il prototipo nel file nel quale la funzione sara’ usata<br />
o Def<strong>in</strong>isci la funzione prima che sia chiamata da ogni<br />
altra funzione (funzione A e funzione B:chi deve essere<br />
dichiarata prima se l’una chiama l’altra)
Funzioni:def<strong>in</strong>izioni<br />
Funzione prototipo e’ uno statement ( ; ) che consiste: del tipo del<br />
val<strong>ore</strong> che ritorna la funzione, del nome e della lista dei parametri<br />
che entrano<br />
es. long Area(<strong>in</strong>t base,<strong>in</strong>t altezza=20); //20 e’ un default qualora<br />
//non immetti l’altezza nell’implementazione<br />
Def<strong>in</strong>izione di funzione:consiste di un header e del corpo della funzione<br />
stessa.<br />
Header:=prototipo con I parametri che devono avere un nome e non ci<br />
sono ( ; ) (vedi il primo esempio più complicato all’<strong>in</strong>izio).<br />
Es.<br />
Long Area(long l,long h) //puoi passare come argomenti<br />
{ //anche altre funzioni o se stessa<br />
return l*h;<br />
//(recursione)<br />
}
Variabili locali e globali<br />
• Locale=def<strong>in</strong>ita dentro una funzione(blocco) e<br />
visibile solo dentro una funzione (blocco)( vale<br />
solo all’<strong>in</strong>terno delle parentesi grafe e non puo’<br />
cambiare una variabile con lo stesso nome fuori<br />
del blocco ).<br />
• Globale=def<strong>in</strong>ite fuori ogni funzione e visibili da<br />
ogni funzione del programma.,<br />
(sono molto pericolose <strong>in</strong> <strong>C++</strong> perche’ la stessa<br />
variabile puo’ essere cambiata da piu’ funzioni <strong>in</strong><br />
maniera <strong>in</strong>visibile alle altre)
Funzioni: esempio 1<br />
#<strong>in</strong>clude <br />
Void myFunction();<br />
Int x=5,y=7;<br />
Int ma<strong>in</strong>()<br />
{<br />
Cout
Funzioni:esempio2 multiple return<br />
#<strong>in</strong>clude <br />
Int Doubler (<strong>in</strong>t AmountToDouble);<br />
Int ma<strong>in</strong>()<br />
{<br />
Int result=0;<br />
Int <strong>in</strong>put;<br />
cout
Funzioni: overload<strong>in</strong>g o<br />
polimorfismo<br />
Funzioni con stesso nome e ma differente lista di parametri<br />
di <strong>in</strong>put (per numero o tipo) e return type si dicono<br />
polimorfe.<br />
Per esempio vuoi un funzione che ti raddoppi qualunque<br />
cosa tu gli passi (<strong>in</strong>teri,float,double ..)<br />
Es di prototipo:<br />
<strong>in</strong>t Double(<strong>in</strong>t);<br />
float Double(float);<br />
double Double(double);<br />
Analoga la def<strong>in</strong>izione di queste funzioni.<br />
A seconda di cosa gli passi nel programma lui usa una<br />
delle forme di questa funzione Double.
Classi<br />
Il cu<strong>ore</strong> del <strong>C++</strong>
Classi<br />
In <strong>C++</strong> puoi dichiarare una variabile essere <strong>in</strong>tera ma PUOI ANCHE<br />
CREARNE DI NUOVI TIPI.<br />
Def:Classe e’ una collezione di variabili comb<strong>in</strong>ate da un set di relative<br />
funzioni che agiscono su loro e portano ad un effetto che la<br />
caratterizza<br />
Una classe porta alla costituzione di un nuovo tipo di variabili che<br />
chiameremo piu’ generalmente oggetti<br />
Es.Pensiamo alla macch<strong>in</strong>a come ad un nuovo tipo di oggetto fatto da<br />
membri <strong>in</strong>terni (ruote,volante,mot<strong>ore</strong>) e caratterizzato dalla<br />
possibilita’di compiere azioni come accellerare frenare o altro.<br />
Una classe ti permette di <strong>in</strong>capsulare <strong>in</strong> un unico misterioso e<br />
disegnato ad hoc ente, delle proprieta’ che ti servono per il tuo<br />
scopo.Non ti preoccupare di come e’ fatto! Basta che tu sappia cosa<br />
fa e che sta <strong>in</strong> un punto ben def<strong>in</strong>ito del tuo Hard Disk~~~~~
Uso delle classi:creazione di un tipo<br />
Se una classe esiste non la creare:usala o modificala.<br />
Per dichiarare una classe usa la parola chiave “class”<br />
es:<br />
class Cat<br />
{ unsigned <strong>in</strong>t peso; peso e eta sono le variabili <strong>in</strong>terne al gatto<br />
=membri (anche altre classi potrebbero essere membri)<br />
unsigned <strong>in</strong>t eta;<br />
Meow();<br />
meow() e’una funzione <strong>in</strong>terna del gatto=metodo<br />
}; c’e’ la semicolonna<br />
Questa <strong>in</strong>struzione dice al compilat<strong>ore</strong> cosa e’ un gatto quali dati<br />
contiene e cosa fa (meow()) ma NON ALLOCA MEMORIA per il<br />
gatto che e’ un tipo come un <strong>in</strong>tero o un float.
Uso delle<br />
classi:creazionedell’oggetto<br />
Int peso;<br />
Cat Frisky;<br />
Frisky e’ un oggetto del tipo gatto e come tale avra’ un<br />
peso e un eta e potra eseguire la funzione meow()<br />
Qui la memoria viene allocata a Frisky<br />
Un oggetto e’ una <strong>in</strong>dividuale istanza di una classe mentre<br />
la classe e’ solo l’idea.<br />
Un oggetto di tipo gatto non puo’ fare altre azioni oltre<br />
Meow().<br />
Per accedere ai membri della classe o ai metodi usi:( . )<br />
Frisky.peso=50;<br />
Friscky.Meow() eseguira’ la funzione Meow()
Public vs private<br />
Di default tutti I membri di una classe sono privati (=accessibili solo con<br />
metodi di quella classe) mentre public significa che possono essere<br />
accessibili da tutti.<br />
Se scrivo nell’esempio di prima<br />
Frisky.peso=50;<br />
avro’ un err<strong>ore</strong> perche’ di default il peso e’ privato e si puo’ agire su di<br />
esso solo tramite funzioni di quella classe.Dovro’ creare una<br />
funzione publica SetPeso() all’<strong>in</strong>terno dell’idea gatto o dichiaro<br />
pubblico il membro peso nella dichiarazione tramite<br />
Class cat {<br />
La regola migli<strong>ore</strong> e’ mantenere le variabili<br />
Public:<br />
private(visibili solo da metodi <strong>in</strong>terni) e creare<br />
<strong>in</strong>te peso,eta; metodi pubblici per agire su tali variabili <strong>in</strong><br />
maniera da mantenere <strong>in</strong>capsulata la classe<br />
Private:<br />
=metodi pubblici di accesso<br />
Meow();}
Uso classi:un primo esempio<br />
#<strong>in</strong>clude <br />
class Car<br />
{<br />
public:<br />
//metodi pubblici<br />
void Start();<br />
void accelerate();<br />
void setYear(<strong>in</strong>t Year); //dichiarazione della classe Car<br />
<strong>in</strong>t GetYear();<br />
private:<br />
<strong>in</strong>t theYear;<br />
//variabili private<br />
char Model[255];<br />
};<br />
Car BMW530;<br />
Int immatricolazione;<br />
BMW530.SetYear(i99);<br />
immatricolazione=BMW530.getYear(); //che hanno sara’ la BMW
Costruttori e distruttori<br />
Sono metodi particolari<br />
Int anno; e poi anno=99; // per le variabili normali<br />
Oppure <strong>in</strong>t anno=99;<br />
Stessa cosa la puoi immag<strong>in</strong>are per le classi.L’<strong>in</strong>izializzazione comb<strong>in</strong>a la<br />
dichiarazione e l’assegnazione di valori di default usando speciali metodi<br />
che NON ritornano valori ma che prendono parametri con cui settare I<br />
membri all’<strong>in</strong>izio.<br />
Il costrutt<strong>ore</strong> per la classe Car si def<strong>in</strong>ira’:<br />
Class Car<br />
{<br />
public:<br />
Car(<strong>in</strong>t <strong>in</strong>itialAge);<br />
~Car(); //Metodo distrutt<strong>ore</strong>:ogni volta che dichiari un costrutt<strong>ore</strong><br />
<strong>in</strong>t GetYear(); <strong>in</strong>t SetYear(<strong>in</strong>t anno);<br />
private: <strong>in</strong>t TheYear;<br />
};
Implementazione di un metodo<br />
Una funzione accessoria e’ un <strong>in</strong>terfaccia fra I dati privati di un<br />
oggetto e il resto del mondo.<br />
I metodi come ogni funzione sono implementati dopo essere dichiarati<br />
Ogni def<strong>in</strong>izione di una funzione membro avviene con la s<strong>in</strong>tassi:<br />
tipo Classe-tipo::nome metodo { azione; }<br />
Es <strong>in</strong>t Car::GetYear{ return theYear ;}<br />
Es void Car::SetYear(<strong>in</strong>t anno) {theYear=anno;}<br />
Qu<strong>in</strong>di:<br />
<strong>in</strong>t ma<strong>in</strong>() {<br />
Car BMW530;<br />
BMW530.SetYear(99);<br />
Cout
Implementazione del costrutt<strong>ore</strong><br />
Dopo la dichiarazione di sopra implementi I<br />
metodi:<br />
Cat::Cat(<strong>in</strong>t <strong>in</strong>itialAge)<br />
{ theYear=<strong>in</strong>itialAge;} non ci vuole il ; come ogni fun.<br />
Cat::~Cat() {} //puo’ anche non fare nulla ma lo devi fare<br />
A questo punto quando crei un oggetto tipo<br />
BMW530 lo puoi creare anche come:<br />
Car BMW530(99); che assume di default l’anno<br />
99 di immatricolazione
Interfaccia contro<br />
implementazione<br />
Una classe da come si vede si divide <strong>in</strong> due parti :<br />
1. Dichiarazione<br />
2. Implementazione<br />
La maggior parte delle volte tu non devi scrivere ma usare<br />
una classe e <strong>in</strong>formi il tuo programma di leggersela da<br />
file con <strong>in</strong>clude.<br />
In genere vale la regola che nel file header (.h) si metta la<br />
dichiarazione e il path dove trovare il file di dimensione<br />
.cc dove <strong>in</strong>vece c’e’ l’implementazione di tutti I metodi.<br />
Il contratto con il cliente della classe sta nel .h dove sono<br />
contenute tutte le <strong>in</strong>formazioni della classe.<br />
Esistono certi metodi implementati nello stesso punto dove<br />
sono dichiarati:si usa <strong>in</strong>l<strong>in</strong>e <strong>in</strong>t…..
Classi con altre classi come membri:<br />
un esempio<br />
Classi complesse possono anche usare come dati altre classi piu’<br />
semplici.<br />
Vediamo questo esempio completo dell’uso di classi <strong>in</strong> un ma<strong>in</strong>.<br />
//beg<strong>in</strong> rect.h<br />
#<strong>in</strong>clude lo usa solo rect.h e qu<strong>in</strong>di non c’e’ bisogno altrove<br />
Class Po<strong>in</strong>t<br />
{ public:<br />
Void SetX(<strong>in</strong>t x) {itsX =x;} implementazione <strong>in</strong>l<strong>in</strong>e<br />
Void SetY(<strong>in</strong>t y) {itsY =y;} implementazione <strong>in</strong>l<strong>in</strong>e<br />
Int GetX() {return itsX;}<br />
Int GetY() {return itsY;}<br />
private:<br />
};<br />
<strong>in</strong>t itsX,itsY;
Segue esempio<br />
Class Rectangle<br />
{<br />
Public:<br />
Rectangle (<strong>in</strong>t top,<strong>in</strong>t left,<strong>in</strong>t bottom,<strong>in</strong>t right);<br />
~Rectangle() {}; <strong>in</strong>l<strong>in</strong>e implementazione<br />
<strong>in</strong>t GetTop() {return itsTop;}<br />
<strong>in</strong>t GetLeft() {return itsLeft;}<br />
<strong>in</strong>t GetBottom() {return itsBottom;}<br />
<strong>in</strong>t GetRight() {return itsRight;}<br />
void SetTop(<strong>in</strong>t Top) {itsTop=Top;}<br />
void SetLeft(<strong>in</strong>t Left) {itsLeft=Left;}<br />
void SetBottom(<strong>in</strong>t Bottom) {itsBottom=Bottom;}<br />
void SetRight(<strong>in</strong>t Right) {itsRight=Right;}<br />
Po<strong>in</strong>t GetUpperLeft() {return itsUpperLeft;}<br />
Po<strong>in</strong>t GetLowerLeft() {return itsLowererLeft;}<br />
Po<strong>in</strong>t GetUpperRight() {return itsUpperRight;}<br />
Po<strong>in</strong>t GetLowerRight() {return itsLowerRight;}<br />
Int GetArea();<br />
//metodo di rectangle di tipo Po<strong>in</strong>t
Segue esempio<br />
Private:<br />
Po<strong>in</strong>t itsUpperLeft;<br />
Po<strong>in</strong>t itsLowerLeft;<br />
Po<strong>in</strong>t itsUpperRight;<br />
Po<strong>in</strong>t itsLowererLeft;<br />
<strong>in</strong>t itsTop;<br />
<strong>in</strong>t itsLeft;<br />
<strong>in</strong>t itsBottom;<br />
<strong>in</strong>t itsRight;<br />
};<br />
//end rect.h ora usiamo quanto dichiarato<br />
#<strong>in</strong>clude <br />
Rectangle::Rectangle(<strong>in</strong>t top,<strong>in</strong>t left,<strong>in</strong>t bottom,<strong>in</strong>t right)<br />
{<br />
itsTop=top,itsLeft=left,itsBottom=bottom,itsRight=right;<br />
itsUpperLeft.SetX(left);<br />
itsUpperLeft.SetY(top);<br />
itsUpperRight.SetX(right);<br />
itsUpperRight.SetY(top);<br />
itsLowerLeft.SetX(left);<br />
itsLowerLeft.SetY(bottom);<br />
itsLowerRight.SetX(right);<br />
itsLowerRight.SetY(bottom);<br />
}
Segue esempio<br />
Int rectangle::GetArea()<br />
{<br />
<strong>in</strong>t width =itsRight-itsLeft;<br />
Int height=itstop-itsBottom;<br />
return (Width*Height);<br />
}<br />
Int ma<strong>in</strong>()<br />
{<br />
Rectangle ilMioRettangolo(100,20,50,80);<br />
<strong>in</strong>t Area =ilMioRettangolo.GetArea();<br />
cout
Loop <strong>in</strong> <strong>C++</strong><br />
(goto,while,do, for)
Loop<strong>in</strong>g<br />
1.) goto “label name” // label=nome seguito dai :<br />
(<strong>in</strong> genere il nome della label e’ loop per non perdere il<br />
significato)<br />
<strong>in</strong>t ma<strong>in</strong>()<br />
{<br />
<strong>in</strong>t counter=0; //l’uso di goto conduce a spaghetti codes<br />
loop: counter++;<br />
cout
Loop<strong>in</strong>g<br />
2.)while(condizione){…} //loop:ilblocco “{…}” che viene<br />
//eseguito f<strong>in</strong> quando la condizione <strong>in</strong>iziale e’ VERA.<br />
<strong>in</strong>t ma<strong>in</strong>() {<br />
<strong>in</strong>t counter=0;<br />
while(counter
Loop<strong>in</strong>g:Cont<strong>in</strong>ue e break<br />
Se vuoi fare un loop prima che sia f<strong>in</strong>ito<br />
l’<strong>in</strong>tero set di statements nel blocco while<br />
Usi cont<strong>in</strong>ue (ritorni alla testa del loop)<br />
Se vuoi uscire dal loop prima che sia f<strong>in</strong>ita la<br />
condizione usi break.<br />
Utile per esempio <strong>in</strong> loop <strong>in</strong>f<strong>in</strong>iti tipo while(1)<br />
per cui ti <strong>in</strong>terrompi se certe condizioni<br />
sono raggiunte.
Loop<strong>in</strong>g<br />
3.)Do {…}while;:l’esecuzione del blocco (o del<br />
s<strong>in</strong>golo statement) e’ garantita almeno una<br />
volta.<br />
Int ma<strong>in</strong>(){<br />
<strong>in</strong>t counter=0;<br />
do<br />
{<br />
counter++;<br />
cout
Loop<strong>in</strong>g<br />
4.) for(<strong>in</strong>izializzazione;condizione;<strong>in</strong>cremento) {…}<br />
Questo modo comb<strong>in</strong>a I tre step <strong>in</strong> una sola volta.<br />
<strong>in</strong>t ma<strong>in</strong>() {<br />
for(counter=0;counter
Un esempio di loop concatenati<br />
Int ma<strong>in</strong>() {<br />
<strong>in</strong>t righe,colonne;<br />
char theChar;<br />
cout
Switch statement:evitare if troppo concatenati<br />
Valuta una espressione e divide l’azione a seconda dei valori che tira<br />
fuori questa espressione<br />
S<strong>in</strong>tassi:: switch (espressione)<br />
{<br />
case val<strong>ore</strong>1 :statement1; //o un blocco {}<br />
case val<strong>ore</strong>2 :statement2;<br />
……….<br />
case val<strong>ore</strong>N :statementN;<br />
case default :statement; // ci switcha se nessun caso e’ vero<br />
} //altrimenti esce senza far nulla
Un esempio di ricapitolazione<br />
#<strong>in</strong>clude <br />
Enum BOOL {FALSE,TRUE}<br />
typedef unsigned short <strong>in</strong>t USHORT;<br />
USHORT menu();<br />
void DoTaskOne();<br />
void DoTaskMany(USHORT);<br />
<strong>in</strong>t ma<strong>in</strong>()<br />
{<br />
BOOL exit =FALSE;<br />
for ( ; ;)<br />
{<br />
USHORT choice =menu();<br />
switch(choice)<br />
{ case(1):DoTaskOne();<br />
break;<br />
case(2) :DoTaskMany(2);<br />
break; //pui usare il break per uscire da un do while loop ma anche da un for <strong>in</strong>f<strong>in</strong>ito e da uno switch statement<br />
case(3):DoTaskmany(3);<br />
break;<br />
case(4): break;<br />
case(5):exit=TRUE;<br />
break;<br />
default: cout
Un esempio di ricapitolazione<br />
USHORT menu()<br />
{ implementazione delle funzioni usate<br />
USHORT choice;<br />
cout
PUNTATORI
Puntatori<br />
Una variabile e’ allocata <strong>in</strong> un unica locazione di memoria nota come il<br />
suo <strong>in</strong>dirizzo che viene assegnato dal compilat<strong>ore</strong><br />
una volta dichiarata la variabile.<br />
Per conoscere l’<strong>in</strong>dirizzo di una variabile basta che usi l’operat<strong>ore</strong> di <strong>in</strong>dirizzo &<br />
:<br />
<strong>in</strong>t var =10;<br />
cout
Puntatori<br />
Se non <strong>in</strong>izializzi un puntat<strong>ore</strong> devi specificamente assegnare l’<strong>in</strong>dirizzo<br />
di qualche variabile (cioe’ e’ buona norma evitare di avere wild po<strong>in</strong>ter<br />
ovvero puntatori NON assegnati) oppure assegnargli zero se non sai<br />
che val<strong>ore</strong> dare (puntat<strong>ore</strong> nullo).<br />
unsigned short <strong>in</strong>t Eta=50; //dichiara la variabile e assegna un val<strong>ore</strong><br />
unsigned short <strong>in</strong>t *pEta= Η //dichiara un po<strong>in</strong>ter e il val<strong>ore</strong><br />
L’asterisco ha anche un’azione <strong>in</strong>versa:da un puntat<strong>ore</strong> puoi<br />
dereferenzare e conoscere il val<strong>ore</strong> della variabile all’<strong>in</strong>dirizzo<br />
di cui il puntat<strong>ore</strong> ha il val<strong>ore</strong> e non solo dichiarare<br />
<strong>in</strong>t LaMiaeta=*pEta; (* significa il val<strong>ore</strong> storato all’<strong>in</strong>dirizzo pEta)<br />
*pEta=5;<br />
Per evitare confusioni pensa alla seguente equivalenza<br />
variabileval<strong>ore</strong> come puntat<strong>ore</strong><strong>in</strong>dirizzo di una variabile
Perche’ I puntatori<br />
Se tu hai gia’ una variabile con cui accedere ad un<br />
certo dato perche’ <strong>in</strong>ventarsi allora una variabile che<br />
porta <strong>in</strong>formazioni dell’<strong>in</strong>dirizzo di questa variabile<br />
con cui ritrovare quel val<strong>ore</strong><br />
Tre sono I motivi<br />
1.Maneggiare dati nel free st<strong>ore</strong><br />
2.Accedere ai membri e ai metodi di una classe<br />
(da comb<strong>in</strong>are con il polimorfismo per event-driven)<br />
3.Passare variabili a funzioni per riferimento<br />
Vedremo ora il punto 1.
Memoria usata<br />
• Stack variabili locali di funzioni cancellata quando la funzione<br />
f<strong>in</strong>isce<br />
• Code space riservata al codice<br />
• Global space name variabili globali del programma<br />
• Registro funzioni <strong>in</strong>terne come per esempio mantenere traccia<br />
dell’<strong>in</strong>izio dello stack.<br />
• Free st<strong>ore</strong> tutto il resto che viene cancellato alla term<strong>in</strong>azione del<br />
programma<br />
Primo problema:le variabili locali non persistono e<br />
l’uso di variabili globali rende difficile da mantenere<br />
il codice.
Puntatori:new e delete<br />
Il comando new ti permette di allocare memoria nel free st<strong>ore</strong>. New<br />
ritorna un <strong>in</strong>dirizzo di memoria del free st<strong>ore</strong>.<br />
La s<strong>in</strong>tassi e’:<br />
<strong>in</strong>t * pPo<strong>in</strong>ter=new <strong>in</strong>t; che ora punta ad un <strong>in</strong>tero nel free st<strong>ore</strong>.<br />
Qu<strong>in</strong>di puoi usarlo come ogni altro puntat<strong>ore</strong>: *pPo<strong>in</strong>ter=75;<br />
(assegna il val<strong>ore</strong> 75 all’area nel free st<strong>ore</strong> alla quale punta pPo<strong>in</strong>ter)<br />
NB.quando hai f<strong>in</strong>ito con la tua area di memoria devi usare il<br />
comando delete per liberare la memoria<br />
delete pPo<strong>in</strong>ter; (libera la memoria cui pPo<strong>in</strong>ter puntava:OBBLIGATORIO)<br />
Il vantaggio nel modo di accedere alla memoria piuttosto che con<br />
var.globlali sta nel fatto che solo funzioni con accesso al<br />
puntat<strong>ore</strong> hanno accesso a quei dati “globali” elimando il<br />
problema che una funzione cambia <strong>in</strong> modo <strong>in</strong>aspettato e<br />
<strong>in</strong>cotrollato quel dato stesso!
Creare oggetti nel free st<strong>ore</strong><br />
Gia come puoi creare un puntat<strong>ore</strong> ad un<br />
<strong>in</strong>tero lo puoi fare per una classe e qu<strong>in</strong>di ad<br />
un oggetto<br />
Cat *pCat =new Cat;<br />
delete pCat;<br />
(Non chiamare piu’ volte delete su uno stesso<br />
puntat<strong>ore</strong>:avrai un crash del tuo programma .<br />
La soluzione dopo delete e’ settare 0 quel puntat<strong>ore</strong><br />
per essere sicuri al 100%)<br />
Delete implica la chiamata del distrutt<strong>ore</strong> di quella<br />
classe
Accedere ai membri e ai metodi di una<br />
classe tramite il puntat<strong>ore</strong> alla medesima<br />
Accedi alle funzioni/membri di una classe con l’operat<strong>ore</strong> ( . ).Se<br />
pero’ tratti con puntatori prima devi dereferenzare (*) il<br />
puntat<strong>ore</strong> all’oggetto: (*pCar).GetYear(); C’e’ un modo piu’<br />
compatto:<br />
pCar->GetYear(); Esempio:<br />
#<strong>in</strong>clude<br />
class Cat<br />
{<br />
public:<br />
Cat() {itsAge=2;}<br />
~Cat() {cout
Puntatori:segue esempio<br />
Int ma<strong>in</strong>()<br />
{<br />
}<br />
Cat * Melissa =new Cat;<br />
cout
Il puntat<strong>ore</strong> this<br />
Ogni membro di una classe ha un parametro<br />
nascosto : il puntat<strong>ore</strong> “this”In ogni chiamata di<br />
un metodo <strong>in</strong>terno (GetAge(),SetAge()) anche il<br />
puntat<strong>ore</strong> this per quell’oggetto e’<br />
<strong>in</strong>cluso.Tuttavia spesso e’ utile utilizzare<br />
esplicitamente this per il potere che hanno I<br />
puntatori come nell’esempio<br />
void SetLenght(<strong>in</strong>t length) {this->itsLength=length;}<br />
THIS stora <strong>in</strong>fatti l’<strong>in</strong>dirizzo di memoria dell’oggetto <strong>in</strong><br />
questione(theCat,Frisky,BMW520 etc.etc)
Precauzioni.<br />
• Cerca sempre di <strong>in</strong>izializzare un puntat<strong>ore</strong> (magari anche assegnando 0<br />
quando si puo’.)(W<strong>IL</strong>D POINTERS)<br />
• Ogni puntat<strong>ore</strong> nel free st<strong>ore</strong> deve essere cancellato prima di essere<br />
riassegnato ad una nuova locazione con NEW (altrimenti non vedi la<br />
memoria occupata all’ <strong>in</strong>dirizzo del primo puntat<strong>ore</strong> f<strong>in</strong> quando il<br />
programma non term<strong>in</strong>a)<br />
• Evitare di provare ad usare un puntat<strong>ore</strong> che e’ stato precedentemente<br />
cancellato con delete senza riassegnarlo :STRAY POINTERS<br />
• Evitare di cancellare piu’ volte uno stesso puntat<strong>ore</strong>:ad ogni new c’e’ un<br />
delete.Per essere sicuri dopo un delete assegna 0 al puntat<strong>ore</strong><br />
• Se new non puo’ allocare memoria nel free st<strong>ore</strong> ritorna il puntat<strong>ore</strong><br />
nullo:qu<strong>in</strong>di mai assegnare ad un esistente puntat<strong>ore</strong> del free st<strong>ore</strong> il<br />
val<strong>ore</strong> zero.Questo significa che NON sempre e’ possibile <strong>in</strong>izializzare<br />
puntatori, ma ricordati che HAI l’obbligo di assegnarli PRIMA O POI.<br />
E’ LECITA DUNQUE ANCHE LA SINTASSI :<br />
<strong>in</strong>t *pPo<strong>in</strong>ter; //senza <strong>in</strong>izializzazione mi <strong>in</strong>forma solo che pPo<strong>in</strong>ter punta<br />
//ad un <strong>in</strong>tero<br />
pPo<strong>in</strong>ter=new <strong>in</strong>t; //crea nel free st<strong>ore</strong> Non so che val<strong>ore</strong> dargli ma non gli