Il 0% ha trovato utile questo documento (0 voti)
22 visualizzazioni27 pagine

Informatica 4

Caricato da

lock0.bat
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
22 visualizzazioni27 pagine

Informatica 4

Caricato da

lock0.bat
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Sei sulla pagina 1/ 27

DISPENSE DI INFORMATICA CLASSE QUARTA ITI

Capitolo 1 Liste

La principale applicazione dei puntatori associati alle strutture di dati consiste nella creazione di liste.
Possiamo assimilare una lista ad una struttura (vettore di record) di lunghezza indefinita.
Il codice minimo per realizzare una lista a puntatori è il seguente dove ogni record è costituito da due
campi, uno intero ed un altro è un puntatore all’elemento successivo:

#include<iostream>
using namespace std;
struct T{
int x;
struct T *y;
};
main(){
T *p,*q=NULL,*j=NULL;
bool primo=true;
//caricamento
do{
p=new T;
cout<<"ins:";cin>>p->x;
p->y=NULL;
if(primo){
j=p;
q=p;
primo=false;
}else{
q->y=p;
q=p;
}//fine if
}while(p->x);
//scrittura a video
1
p=j;//p punta al primo elemento con j
while(p->x){
cout<x<<" ";
p=p->y;
} //fine while
} // fine main

Viene dichiarato una struttura


record costituita da una variabile
intera x ed una variabile puntatore
ad un'altra struttura T che
chiamiamo y

il puntatore p va a puntare la parte


intera di un record: mentre il
puntatore p->y punta a NULL ( ed è
comunque inizializzato).

solo se siamo al primo giro del ciclo


do, i tre puntatori vengono riferiti allo
stesso elemento.

nel secondo giro viene allocato lo


spazio per un nuovo elemento:
p=new T;
p punta alla parte intera del nuovo
elemento entrante mentre con la
istruzione
q->y=p;
consentiamo al primo elemento di
riferirsi al secondo.

2
sempre al secondo giro (e anche in
quelli successivi) è necessario un
ulteriore movimento:
q=p;
in questo modo j rimane da solo a
puntare al primo elemento.

Al terzo giro p punta al nuovo


elemento entrante mentre il secondo
elemento di struttura T punterà al
terzo tramite l'istruzione:
q->y=p;

poi q viene riposizionato sull'ultimo


elemento assieme a p con l'istruzione:
q=p;

nei giri successivi questo comportamento si ripete, va avanti finché l'utente non inserisce come valore 0.
La scansione della lista viene effettuata portando p a puntare al primo elemento con l'istruzione:
p=j;
la stampa è eseguita dal ciclo while
while(p->x){
cout<x<<" ";
p=p->y;
}
incrementando ogni volta la posizione di p nella lista con:
p=p->y;

1.1ESEMPIO DI OPERAZIONE SU LISTE :INSERIMENTO IN CIMA ALLA


LISTA DI UN ELEMENTO

La struttura di record per la lista è quella in cima al capitolo 1

3
Void inserimentointesta(Void)

T *TDL /*puntatore iniziale della lista */

T *Pnuovo=NULL;/* puntatore ausiliario */

Pnuovo =new T;

Cin>> pnuovo->x;

Pnuovo->y=NULL;

If (TDL != NULL)

Pnuovo->Y=TDL;

TDL=Pnuovo;

1.2 ESEMPIO DI OPERAZIONE SU LISTE : RIMOZIONE IN CIMA ALLA


LISTA DI UN ELEMENTO

Void inserimentointesta(Void)

{
T *TDL; /*puntatore iniziale della lista */
T *P;/* puntatore ausiliario */
If (TDL!=Null) /* se la lista non è vuota */
{
P=TDL;
TDL=P->Y
Delete p;
}

4
1.3 ESEMPIO DI OPERAZIONE SU LISTE :RICERCA DI UN ELEMENTO
IN UNA LISTA

Struct Nodo {
Int info;
nodo * psucc}

nodo * p;
nodo * piniz;
void lista ()
{
IF (piniz = =NULL)
Cout<< “La lista è vuota”;
else
{
Conta=0;
p=piniz;
While (p!= NULL)
{
p=p>psucc;
conta=conta +1
}
}
Cout<< “La lista contiene il seguente numero di elementi
“<<conta

5
1.4 ESEMPIO DI OPERAZIONE SU LISTE : CONTA LE OCCORRENZE DI
UN ELEMENTO IN UNA LISTA

STRUCT Nodo {
Int info;
Nodo *psucc }
Nodo *TDL, *p, *pnuovo=NULL;

Void contanumero ();


{
Int numero, conta=0;
cin>>numero;
If (TDL==NULL)
{
pnuovo= new nodo
pnuovo->info= numero;
pnuovo->psucc=NULL;
TDL=pnuovo
}
Else
P=TDL;

While (p!=NULL)
{
If (p->info==numero)
Conta=conta+1;
p=p->psucc
}
6
If (conta==0)
Cout<<”il numero non esiste nella lista”
Else cout <<”IL numero appare nella lista”<<conta<<”Volte”<<

CAPITOLO 2 PILE E CODE

Una pila è una struttura di dati simile alla lista dove le uniche operazioni consentite sono la inserzione di un
elemento in testa alla lista ( PUSH) e la cancellazione di un elemento sempre in testa alla lista (POP). La
gestione è di tipo LIFO (Last in first out) cioè l’ultimo entrato è anche il primo ad uscire.

Dove (testa) è il puntatore iniziale della lista, quello che punta al primo elemento.

La coda invece è una struttura dati di tipo FIFO ( First in first out) cioè gli inserimenti avvengono alla fine e le
eliminazioni in cima alla coda, è simile alla coda degli sportelli degli Uffici Pubblici. La gestione della coda
avrà bisogno di due puntatori, il primo punterà alla testa della coda ed il secondo all’ultimo elemento.

2.1 ESEMPIO DI INSERIMENTO DI UN NODO IN UNA CODA

void Push()
{
7
int DatoInp; // dato da inserire

T *nuovo; // puntatore ad un nuovo nodo

cout << "Dato da inserire = ";

cin >> DatoInp;

nuovo = new T; // alloca la memoria per il nuovo nodo

nuovo->X = DatoInp;

nuovo->Y = NULL;

if (testa == NULL) testa = nuovo;

else fine->Y = nuovo;

fine=nuovo ;

}/* fine push */

8
CAPITOLO 3 INTRODUZIONE ALLA PROGRAMMAZIONE ORIENTA TA
AGLI OGGETTI

La programmazione strutturata è la costruzione di programmi ordinati basati sull’uso delle strutture


di controllo e sull’organizzazione modulare del codice, con la suddivisione dei programmi in moduli
funzionalmente indipendenti (funzioni).

Vent’anni di programmazione strutturata hanno evidenziato che i benefici apportati da questa tecnica
di programmazione non sono sufficienti a garantire un’abbondante riutilizzo del software
implementato. A partire dagli anni 80 si è quindi sviluppato un nuovo stile di scrittura del codice che
ne consente un reimpiego sempre maggiore.

L’idea è di per sé molto semplice rivoluziona il modo di implementare il codice inserendo un nuovo
approccio, rappresentato dai dati del problema. Questo modo di programmare si chiama
programmazione orientata agli oggetti.

La programmazione orientata agli oggetti non presuppone l’eliminazione delle tecniche precedenti ,
ma piuttosto le completa aggiungendo loro una nuova dimensione.

La programmazione orientata agli oggetti in breve OOP prende il nome dall’elemento su cui si basa:
l’oggetto .

Il programma realizzato con orientamento ad oggetti, si sviluppa attraverso le interazioni tra gli
oggetti: durante l’esecuzione del programma, gli oggetti possono cambiare il loro stato e possono
richiedere l’esecuzione di operazioni associate ad altri oggetti.

La programmazione orientata agli oggetti procura diversi vantaggi:

 Facilità di lettura e di comprensione del codice anche per persone diverse dall’autore
 Manutenzione del programma nel tempo per correzioni o miglioramenti
 Robustezza del programma in situazioni critiche o in operazioni che coinvolgono grandi
quantità di dati
 Riusabilità di parti di codice o di moduli funzionali all’interno di altri programmi

9
La struttura di un oggetto è completamente descritta quando vengono elencate le caratteristiche ed i
comportamenti dell’oggetto.

3.1 LA CLASSE

Gli oggetti sono definiti dalle classi.

La classe è la descrizione astratta degli oggetti attraverso gli attributi ed i metodi. Per utilizzare un
oggetto occorre crearlo come esemplare della classe, cioè come un ‘istanza della classe.

Dovendo per esempio realizzare un programma che gestisca la clientela di un’azienda, ossia memorizzi
i dati anagrafici, consentendo l’inserimento di nuovi clienti, eventuali modifiche o cancellazioni.

Ciascun cliente prevede delle informazioni o attributi come il nome, l’indirizzo e il numero di telefono
e delle funzionalità quali l’inserimento, la modifica e la cancellazione.

Una classe viene rappresentata con uno schema grafico detto diagramma di classe che ne evidenzia il
nome, gli attributi ed i metodi.

10
Per esempio la classe cliente è così strutturata:

Gli elementi che formano la classe, attributi e metodi si chiamano membri della classe. Il
raggruppamento dei membri conferisce alla classe il significato di un’unità di programmazione,
riutilizzabile in altri programmi: il controllo dell’esecuzione diventa più facile e la modifica degli
oggetti nel tempo diventa più semplice. Questi aspetti descrivono il concetto di incapsulamento, che è
uno dei concetti alla base della programmazione ad oggetti.

Il termine incapsulamento indica la qualità degli oggetti di poter incorporare al loro interno sia gli
attributi sia i metodi, cioè le caratteristiche e i comportamenti dell’oggetto.

Creazione di una classe

Nel linguaggio C++ le classi inglobano sotto un unico nome i dati membro(attributi) e le funzioni
membro (metodi). Questa modalità di aggregazione rappresenta in pratica il concetto di
incapsulamento della programmazione ad oggetti.

Per dichiarare una classe si usa la seguente sintassi:

11
3.2 C++ PROGRAMMAZIONE ORIENTATA AGLI OGGETTI

Nella programmazione strutturata, viene scritto del codice che serve per manipolare dei dati, in questo
contesto, codice e dati vengono trattati come due elementi separati. La programmazione orientata agli
oggetti, tratta invece, dati ed oggetti come una singola entità chiamata classe. Tutti i programmi OOP
iniziano con una classe. Una classe è una struttura di dati che contiene tutto il necessario per memorizzare e
manipolare i dati. Supponiamo di sviluppare un programma per lo studio sui consumi di veicoli: .

#include
using namespace std;

class V {// classe veicolo


public: //dichiarazione degli attributi
int a;//autonomia (km)
int l;//volume del serbatoio(lt)
};
main(){
V v1;//istanzio l'oggetto v1 di tipo V
v1.a=300;
v1.l=50;
cout<<"il veicolo ha un consumo:" << v1.a/v1.l << "km/l";
}//__________fine main

Uno scritto di questo tipo sarebbe sufficiente per descrivere un veicolo. Ogni classe è dotata di attributi
(membri dati) che sono privati per impostazione predefinita. Noi abbiamo fatto un'eccezione: li abbiamo
dichiarati esplicitamente pubblici, altrimenti non avremmo potuto accedervi.

12
In questo caso i due attributi, a ed l pur facendo parte
dell'oggetto v1, sono accessibili dal mondo esterno.
Raggiungibili con le invocazioni:

v1.a
v1.l

La filosofia di usare variabili locali e di minimizzare le variabili globali all'interno del codice è sempre stata
raccomandata fin da quando la programmazione strutturata, organizzata in funzioni e procedure, ha
soppiantato quella sequenziale, caratterizzata da salti e rinvii fra i vari punti del programma (istruzione
goto).
Nella programmazione ad oggetti (OOP) questa tendenza è stata inasprita, proprio per evitare l'utilizzo di
variabili globali, dato che esse, essendo visibili da tutti i punti del programma, possono influenzare, talvolta
in modo incontrollato, l'esecuzione dello stesso, nonché, rendono difficile la gestione del codice, la sua
manutenzione e il suo sviluppo .

3.2.1 INCAPSULAMENTO

Una classe è una struttura di dati che contiene tutto il necessario per memorizzare e manipolare dati.
Ogni variabile definita all'interno di una classe è denominata attributo, si usa questo termine per distinguerla
da una normale variabile.
All'interno della classe vengono implementate anche le funzioni che manipolano gli attributi, esse sono
denominate metodi.
Dovrebbe essere possibile manipolare gli attributi di una classe solo attraverso i metodi della classe stessa,
non come abbiamo fatto noi, sopra, dove il main può accedere liberamente ai metodi e farne quello che
vuole.

#include < iostream >


using namespace std;
class V {//(veicolo)
int a;//autonomia (km)
int l;//volume del sebatoio(lt)
public:
void seta(int x);//metodi pubblici
int geta();
13
void setl(int y);
int getl();
};
void V::seta(int x){
a=x;
}
int V::geta(){
return a;
}
void V::setl(int y){
l=y;
}
int V::getl(){
return l;
}
main(){
V v1;//istanzio l'oggetto v1 di tipo V
v1.seta(300);
v1.setl(50);
cout << "il veicolo ha un consumo:" << v1.geta()/v1.getl() <<
"km/l";}//__________fine main

14
All'interno del programma
un'eventuale chiamata del tipo:

cout << v1.a;

genera un errore di compilazione


dato che l'attributo a è privato e
dunque inaccessibile.

Sono, invece, stati implementati 4 metodi pubblici: seta e setl per impostare i valori degli attributi

privati a ed l e geta e getl che servono per restituire al programma chiamante i valori di a ed l.

In quest'ultimo caso gli attributi a ed l sono privati ed irraggiungibili dall'esterno.


La loro accessibilità è garantita dai 4 metodi pubblici.

3.2.2 CLASSI ED OGGETTI

La riga di codice
V v1;
serve per istanziare l'oggetto v1 di classe V.
Un'istanza è una nuova copia della struttura definita nella classe (schema degli attributi + metodi
incapsulati: i metodi sono condivisi tra oggetti diversi della stessa classe).
In questa ottica la classe viene interpretata come il 'calco' che serve a 'coniare' un effettivo oggetto che verrà
poi dotato di dati concreti gestito dai corrispondenti metodi.
In altri termini, una classe non è un oggetto, ma una sua descrizione e come tale non occupa memoria.

3.2.3 COSTRUTTORI E DISTRU TTORI

Il costruttore permette all'oggetto appena creato di autoinizializzarsi. Un costruttore è un metodo speciale


che appartiene alla classe e ha il medesimo nome della classe.

#include < iostream >


using namespace std;
15
class V {//(veicolo)
int a;//autonomia (km)
int l;//volume del sebatoio(lt)
public:
void seta(int x);//metodi
void setl(int y);
float consumo();
V(int x,int y);//costruttore
~V();//distruttore
}; //fine classe - implementazione dei metodi
void V::seta(int x){
a=x;
}
void V::setl(int y){
l=y;
}
float V::consumo(){
return (float)a/l;
}
V::V(int x,int y){//implementazione del costruttore
a=x; l=y;
}
V::~V(){//implementazione del distruttore
cout<<"\noggetto distrutto";
}
main(){
V v1(300,40);//istanzio l'oggetto v1 di tipo V
cout< <"il veicolo ha un consumo:"<< v1.consumo()<<
"km/l";
}//__________fine main
Nel listato precedente sono state eliminati i metodi geta() e getl() perché ci interessa conoscere
solo il consumo che ci verrà restituito tramite un apposito metodo pubblico che ci restituisce il rapporto

16
autonomia/litri del veicolo.
Inoltre si nota la dichiarazione e l'implementazione del costruttore. I costruttori non possono restituire
valori.
Il costruttore di un oggetto, è invocato al momento della creazione dell'oggetto medesimo.
Ciò significa che è invocato quando viene eseguita la dichiarazione dell'oggetto. L'output del programma è
il seguente:
il veicolo ha un consumo:7.5km/l
oggetto distrutto
Il complemento costruttore è il distruttore; in numerose circostanze, un oggetto nel momento in cui viene
distrutto deve eseguire una o più azioni (oggetti locali sono creati all'entrata del relativo blocco di codice e
distrutti all'uscita).
Lo scopo principale del distruttore, rimane comunque la deallocazione della memoria precedentemente
richiesta all'atto dell'istanziazione da parte del costruttore.

3.2.4 METODI PRIVATI

Supponiamo ora, che di un determinato veicolo più che del consumo ci interessi il consumo per persona
trasportata; in pratica introdurremo un nuovo parametro, chiamato 'convenienza' che viene definito come:

convenienza = consumo/p

dove con p indichiamo il numero di persone trasportate, in questo modo il metodo consumo() diventa
accessorio al calcolo della convenienza; se di esso non interessa stampare i valori, può anche essere
dichiarato privato.:

#include < iostream >


using namespace std;
const float prz=1.5;
class V {//(veicolo)
int p;//persone trasportate
int a;//autonomia (km)
int l;//volume del sebatoio(lt)
float consumo();//a/l
public:
V(int x,int y,int z);//costruttore
float convenienza();//consumo/p
17
};
float V::consumo(){
return (float)a/l;
}
float V::convenienza(){
return prz*consumo()/p;
}
V::V(int x,int y,int z){
a=x;//autonomia
l=y;//litri di pieno
p=z;//passeggeri
}
main(){ V v1(300,40,3);//istanzio l'oggetto v1 di tipo V
cout << "il veicolo ha convenienza:" << v1.convenienza() <<
"E/persona"; }//__________fine main ;

Notiamo come un'eventuale chiamata


cout << v1.consumo();
introdotta nel main, genera un errore di compilazione. dato che la classe consumo() è privata nell'oggetto
istanziato e non è accessibile da altre parti del programma.

3.2.5 EREDITARIETÀ

Tutti i veicoli hanno delle stesse caratteristiche di base, come si è visto autonomia, volume del serbatoio in
lt, persone trasportate; sappiamo anche che essi subiscono delle classificazioni di massima.
Ad esempio, ci sono moto che possono trasportare solo una persona, mentre altre ne possono trasportare 2.
Ci sono i motocarri e i sidecar; i primi possono trasportare al massimo due persone in cabina (+ il carico) i
secondi non hanno carico e possono trasportare fino a 3 persone.
Poi ci sono auto (che hanno 4 ruote) che possono trasportare 5 persone, ma alcune solo 4.
Il discorso potrebbe dilungarsi coi pullman che arrivano ad avere 6 ruote e un bel po' di passeggeri. Tutte
queste classi possono essere derivate dalla classe base dei veicoli.

18
Il sistema gerarchico dell'ereditarietà può essere illustrato come in figura; per convenzione una freccia punta
dalla classe derivata fino alla classe base.
L'ereditarietà si esplica permettendo ad una classe di incorporarne un'altra nella propria dichiarazione .

Il seguente programma, si propone di gestire soltanto dei veicoli che siano o motoveicoli (max 3 ruote, 3
passeggeri) o autoveicoli (min=max=4 ruote, 5 passeggeri) .

Tutti questi veicoli avranno come caratteristiche comuni:


a=autonomia (in km)
l=volume del serbatoio (in litri)
Questi attributi rimarranno associati alla classe base denominata veicolo. Pensiamo di realizzare altre 2
classi : la classe M (per i motoveicoli) e la classe A (per gli autoveicoli) con gli ulteriori attributi:

p=persone trasportate
r=numero di ruote
Come si nota, se istanziamo un auto di A l'attributo r=4 è assicurato dalla definizione di costante statica:
static const int ruote=4;
Per ciascuno dei mezzi usati deve essere possibile calcolare la convenienza().

Si deduce, come a questo punto, il metodo consumo(), può restare privato all'interno della classe
veicolo, assieme al metodo pubblico convenienza() senza che questi metodi debbano essere
riscritti ulteriormente per le due nuove classi.
#include < iostream >
using namespace std;
const float prz=1.5;
class V {//(veicolo)

19
int a;//autonomia (km)
int l;//volume del sebatoio(lt)
float consumo();//a/l
protected: int p;//passeggeri
//p accessibile solo dalle classi derivate
public: V(int x,int y);//costruttore
float convenienza();//consumo/p
};
V::V(int x,int y){
a=x;//autonomia
l=y;//litri di pieno
}
float V::convenienza(){
return prz*consumo()/p;
}
float V::consumo(){
return (float)a/l;
} //______________________________________fine classe V
class A:public V {
static const int ruote=4;//ruote
public: A(int aut,int ltvol,int pas);//costruttore
};
A::A(int aut,int ltvol,int pas):V(aut,ltvol){//costruttore
p=pas;//passeggeri
r=ruote;
} //______________________________________fine classe A
class M:public V {
int r;//ruote (variabili)
public: M (
int aut, int ltvol,int pas,int ruo);//costruttore
};
M::M(int aut,int ltvol,int pas,int
20
ruo):V(aut,ltvol){//costruttore
p=pas;//passeggeri
r=ruo;//ruote
} //______________________________________fine classe M
main(){
A a1(300,40,5);
cout << "il veicolo ha convenienza:" << a1.convenienza() <<
"E/persona\n"; M m1(200,20,2,3);
cout << "il veicolo ha convenienza:" << m1.convenienza() <<
"E/persona\n";
}//__________fine main

Notare come l'attributo p sia stato iscritto con la clausola protected nella classe V; in tal modo esso sarà
accessibile solo dai metodi delle due classi derivate M ed A, per altri classi diverse da quelle derivate esso
risulterà protetto.
Notare, inoltre, come la costante ruote (numero di ruote) nella classe A (auto) debba essere dichiarata static;
la parola static specifica che questo attributo viene allocato in memoria una sola volta per tutte le istanze
della classe A; diversamente dall'attributo r della classe M che richiede un'allocazione in memoria ad ogni

oggetto riferito alla classe M che viene creato; questo principio non vale solo per le costanti, ma anche per le
variabili. Un altro fatto rilevante è come vengono dichiarati i due costruttori:

A::A(int aut,int ltvol,int pas):V(aut,ltvol)


M::M(int aut,int ltvol,int pas,int ruo):V(aut,ltvol)

osservando i due costruttori si nota come essi non riconoscano i primi due parametri che vengono passati
alla classe base V che li memorizza negli attributi aut (autonomia) ed l (litri del pieno) mentre il
parametro pas viene affidato all'attributo p ed il parametro ruo all'attributo r (però solo nel caso di

motocicli M perché in caso di auto A r=cost=4).

3.2.6 POLIMORFISMO

Per poter essere un linguaggio di programmazione orientato agli oggetti, il linguaggio deve supportare il
polimorfismo.
Il polimorfismo è un principio della OOP che, data una gerarchia di classi di oggetti, offre la possibilità di
usare lo stesso metodo applicato ad oggetti diversi della gerarchia, oppure lo stesso nome per identificare
21
metodi diversi, incapsulati in classi differenti.
Una variante al nostro programma potrebbe essere quella di delegare ad un unico metodo mostra() le
caratteristiche del veicolo; il risultato sarebbe il seguente:

#include < iostream >


using namespace std;
const float prz=1.5;
class V {//(veicolo)
int a;//autonomia (km)
int l;//volume del sebatoio(lt)
float consumo();//a/l
float convenienza();//consumo/p
protected:
int p;//passeggeri
int r;//ruote
//p accessibile solo dalle classi derivate
public: V(int x,int y);//costruttore
void mostra();//output delle caratteristiche
};
V::V(int x,int y){
a=x;//autonomia
l=y;//litri di pieno
}
void V::mostra() {
cout << "autonomia:" << a << "\tpieno:" << l << "\nconsumo:"
<< consumo();
cout << "\tconvenienza:" << convenienza() << "\nruote:" << r
<< endl << endl;
}//fine mostra;
float V::convenienza() {
return prz*consumo()/p;
}

22
float V::consumo(){
return (float)a/l;
} //______________________________________fine classe V
class A: public V {
static const int ruote=4;//ruote
public:
A(int aut,int ltvol,int pas);//costruttore
};
A::A(int aut,int ltvol,int pas):
V(aut,ltvol){//costruttore
p=pas;//passeggeri
r=ruote;
} //______________________________________fine classe A
class M:public V {
public: M(int aut,int ltvol,int pas,int ruo);//costruttore
};
M::M(int aut,int ltvol,int pas,int ruo):
V(aut,ltvol){//costruttore
p=pas;//passeggeri
r=ruo;//ruote - variabili
} //______________________________________fine classe M
main() {
A a1(300,40,5);
a1.mostra();
M m1(200,20,2,3);
m1.mostra();
}//__________fine main

La classe convenienza() può diventare privata, in ogni caso sarà accessibile dal metodo pubblico
mostra() che così potrò essere invocato dal main attraverso le chiamate:

a1.mostra();

23
m1.mostra();

supponiamo,ora, che solo nel caso di motocicli M a 2 o a 3 ruote il programma debba specificare se si tratta
di una moto, di un sidecar o di un motocarro:

#include < iostream >


using namespace std;
const float prz=1.5;
class V {//(veicolo)
protected://IMPORTANTE!!
int a;//autonomia (km)
int l;//volume del sebatoio(lt)
float consumo();//a/l
float convenienza();//consumo/p
int p;//passeggeri
int r;//ruote //p accessibile solo dalle classi derivate
public: V(int x,int y);//costruttore
void mostra();//output delle caratteristiche
};
V::V(int x,int y){
a=x;//autonomia
l=y;//litri di pieno
}
void V::mostra() {
cout << "autonomia:" << a << "\tpieno:" << l <<
"\nconsumo:"<< consumo();
cout << "\tconvenienza:" << convenienza() << "\nruote:" << r
<< endl << endl;
}//fine mostra;
float V::convenienza() {
return prz*consumo()/p;
}
float V::consumo() {
24
return (float)a/l;
} //______________________________________fine classe V
class A:public V {
static const int ruote=4;//ruote
public: A(int aut,int ltvol,int pas);//costruttore
};
A::A(int aut,int ltvol,int pas):V(aut,ltvol) {//costruttore
p=pas;//passeggeri
r=ruote;
} //______________________________________fine classe A
class M:public V {
char tipo[10];
public:
M(int aut,int ltvol,int pas,int ruo,char s[10]);//costruttore
void mostra();
};
M::M(int aut,int ltvol,int pas,int ruo,char
s[10]):V(aut,ltvol){//costruttore
p=pas;//passeggeri
r=ruo;//ruote - variabili
strcpy(tipo,s);
}
void M::mostra() {
cout << "autonomia:" << a << "\tpieno:" << l << "\nconsumo:"
<< consumo();
cout << "\tconvenienza:" << convenienza() << "\nruote:" << r;
cout << "\t\ttipologia:" << tipo << endl << endl; }//fine
mostra;
//______________________________________fine classe M
main(){
A a1(300,40,5);
a1.mostra();
25
M m1(200,20,2,2,"moto"); m1.mostra();
}//__________fine main

La classe M vede ridefinito il metodo mostra() in tal caso, un oggetto di classe M istanziato, dovrò usare
quest'ultimo metodo per l'output a video e non quello riportato nella classe V.
Una importante modifica, riguarda la ridefinizione a 'protected' degli attributi della classe V, questa
commutazione è stata resa necessaria per permettere alla classe derivata M di accedere agli attributi (prima)
privati della classe V.
Abbiamo usato stesso nome per identificare metodi diversi, incapsulati in classi differenti della gerarchia,
dimostrando, così, il principio del polimorfismo.
Nella classe M il metodo mostra() è ulteriormente specializzato per identificare il tipo di veicolo.

SOMMARIO

Capitolo 1 Liste ............................................................................................................................................................ 1


1.1ESempio di operazione su liste :Inserimento in cima alla lista di un elemento ............................ 3
1.2 ESempio di operazione su liste : Rimozione in cima alla lista di un elemento............................. 4
1.3 ESempio di operazione su liste :Ricerca di un elemento in una lista ............................................... 5
1.4 ESempio di operazione su liste : Conta le occorrenze di un elemento in una lista ...................... 6
Capitolo 2 Pile e Code ................................................................................................................................................ 7
2.1 esempio di inserimento di un nodo in una coda ...................................................................................... 7
Capitolo 3 Introduzione alla programmazione orientata agli oggetti..................................................... 9
3.1 La Classe ................................................................................................................................................................ 10
3.2 C++ Programmazione orientata agli oggetti ............................................................................................ 12
3.2.1 Incapsulamento .............................................................................................................................................. 13
3.2.3 Costruttori e distruttori............................................................................................................................... 15
3.2.4 Metodi privati.................................................................................................................................................. 17
3.2.5 Ereditarietà…………………………………………………………………………………………………………………… 18

3.2.6 Polimorfismo………………………………………………………………………………………………………………… 21

26
27

Potrebbero piacerti anche