Anteprima
Vedrai una selezione di 14 pagine su 63
Programmazione B - Tutta la teoria Pag. 1 Programmazione B - Tutta la teoria Pag. 2
Anteprima di 14 pagg. su 63.
Scarica il documento per vederlo tutto.
Programmazione B - Tutta la teoria Pag. 6
Anteprima di 14 pagg. su 63.
Scarica il documento per vederlo tutto.
Programmazione B - Tutta la teoria Pag. 11
Anteprima di 14 pagg. su 63.
Scarica il documento per vederlo tutto.
Programmazione B - Tutta la teoria Pag. 16
Anteprima di 14 pagg. su 63.
Scarica il documento per vederlo tutto.
Programmazione B - Tutta la teoria Pag. 21
Anteprima di 14 pagg. su 63.
Scarica il documento per vederlo tutto.
Programmazione B - Tutta la teoria Pag. 26
Anteprima di 14 pagg. su 63.
Scarica il documento per vederlo tutto.
Programmazione B - Tutta la teoria Pag. 31
Anteprima di 14 pagg. su 63.
Scarica il documento per vederlo tutto.
Programmazione B - Tutta la teoria Pag. 36
Anteprima di 14 pagg. su 63.
Scarica il documento per vederlo tutto.
Programmazione B - Tutta la teoria Pag. 41
Anteprima di 14 pagg. su 63.
Scarica il documento per vederlo tutto.
Programmazione B - Tutta la teoria Pag. 46
Anteprima di 14 pagg. su 63.
Scarica il documento per vederlo tutto.
Programmazione B - Tutta la teoria Pag. 51
Anteprima di 14 pagg. su 63.
Scarica il documento per vederlo tutto.
Programmazione B - Tutta la teoria Pag. 56
Anteprima di 14 pagg. su 63.
Scarica il documento per vederlo tutto.
Programmazione B - Tutta la teoria Pag. 61
1 su 63
D/illustrazione/soddisfatti o rimborsati
Disdici quando
vuoi
Acquista con carta
o PayPal
Scarica i documenti
tutte le volte che vuoi
Estratto del documento

EREDITARIETA'

es: cellulare (classe cellulare) classe oggetti fisici

es: studente (classe studente) classe persone

Studente ha tutte le proprietà di persona (es: nome, cognome, …) + altre specifiche (es: matricola,

anno immatricolazione, …).

Studente eredità da persona → classe studente deriva da classe persona.

Studente (sottoclasse) → persona (super classe) ← docente

In c++:

Nuova classe “D” in base ad una classe già esistente “B” evidenziando le differenze (con possibilità

di riuso).

“D” derivata, “B” classe base (D → B); ogni campo di “B” (dati e funzioni) è anche campo di “D”

→ D eredita da B.

class B {

public:

int f1() {...}

int f2() {...}

private:

int x;

};

class D: public B { //classe D derivata in modo public da B

public:

int f3() {...}

inf f4() {...}

private:

int y;

};

//derivanza public → visibilità all'esterno della classe D dei campi.

es:

f2 public in B → public in D

x private in B → private in D

uso:

int main() {

D O1;

O1.f3();

O1.f2(); //funzione ereditata

O1.f1(); //funzione f1 di D

O1.B::f1(); //funzione f1 di B

B O2;

O2.f2();

O2.f1();

O2.f3(); //errore -> non posso richiamare funzioni di classi ereditate

} – visibilità campi ereditati all'interno della classe D

– funzioni di D possono riferirsi in modo diretto a tutti i campi pubblici di B, MA non ai

campi privati

Soluzioni:

– usa solo funzioni public di B

– campi in B sono dichiarati protected (invece di private)

Protected: tali campi non sono visibili all'esterno della classe (come i private) ma dalle classi

derivate si.

n.b. I costruttori di B non sono ereditati da D.

class persona {

protected:

string nome, cognome, indirizzo;

...

public:

persona() {

nome = "xxx";

cognome = "xxx";

}

persona (string n); string c) {

n[0] = to_upper(n);

c[0] = to_upper(c);

nome = n;

cognome = m;

...

}

};

class studente: public persona {

private:

int matricola;

string CDL, email;

public:

studente() {

matricola = 0; cdl = "xxx"; email = "xxx";

}

int get_matricola() { return matricola; }

void stampa (ostream & dest) {

dest << nome << " " << cognome << endl;

dest << "Matricola: " << matricola << endl;

dest << "Email: " << email << endl;

}

...

};

int main() {

studente s1;

s1.stampa(cout);

cout << s1.get.matricola();

cout << s1.get.indirizzo();

s1.persona::stampa(cout);

}

studente s2("giacomo", "romani")

– invoca il costruttore senza parametri della classe base

– invoca il costruttore con 2 parametri della classe base con costrutto in generale:

class D: public B {

...

public:

D(..N..): B(..M..) //N e M -> numero dei parametri

{...} // prima invoca il costruttore con M parametri di B

stidenti( string n, string c): persona(n,c) {

col = "informatica";

email = n + "." + c + "@studenti.unipr.it";

matricola = 0;

}

};

int main() {

studente s2("Aldo","Tragni"); //invoca costruttore 2 parametri classe persona

s2.stampa(cout); //Aldo Tragni, matricola 0, email:...

s2.persona::stampa(cout); //Aldo Tragni, indirizzo... , Tel...

}

Principio di sostituibilità

E' possibile usare un oggetto di una classe derivata ovunque sia previsto un oggetto della classe

base (ma non viceversa).

es:

class persona {

...

public:

...

bool operator < (persona P) {

if(cognome == p.cognome)

return nome < p.nome;

return cognome < p.cognome;

}

...

};

class studente: public persona {

...

};

int main() {

studente s1("giacomo","verdi");

studente s2("Aldo","tragni");

if(s1<s2) ... // -> operator < (s2) -> oggetto di classe studente passato come parametro di funzione

della classe persona

}

n.b. La classe derivata è un sottotipo della classe base simile a quello detto per le classi:

ofstream → ostream

Ereditarietà

es: classe data_orario

classe data

→ data del giorno (g,m,a)

classe data_con_orario

→ data + ora del giorno (h,m,s)

con ereditarietà: data_con_orario → data

class data {

protected:

int g,m,a;

void avanza_un_giorno() {...}

private:

bool controlla_data() {...}

public:

data() {...}

data (int giorno, int mese, int anno) {

g = giorno; m = mese; a = anno;

if(controlla_data())

throw "errore data";

}

int get_anno() { return a; }

void stampa(...) {...}

};

class data_con_orario: public data {

private:

int sec;

public:

data_con_orario() { res=0; }

data_con_orario (int g, int m, int a): data(G,M,A) { sec=0; }

void set_orario (int h, int m, int s) {

if(h<0 || h>=24 || m<0 || m>=60 || s<0 || s>=60)

throw "errore orario";

else

sec = h*3600+m*60+s;

}

int get_ore() { return sec%3600; }

int get_minuti() {...}

int get_secondi() { return sec%60; }

void stampa (ostream & dest) {

data::stampa(dest);

if(sec!=0) {

dest << "h";

dest << get_ore() << ":" << get_minuti() << ":" << get_secondi();

}

return;

}

data_con_orario operator+ (int h) {

data_con_orario tmp(g,m,a);

tmp.sec = sec+h*3600;

if(tmp.sec >= 86400) {

int n_giorni = temp.sec/86400;

for(int i=1; i<n_giorni; i++)

tmp.avanza_un_giorno();

tmp.sec = tmp.sec-86400;

}

return tmp;

}

bool operator < (data_con_orario D) { //confronta data dell'oggetto di invocazione con data di D

if(data::operator==(D))

return sec<D.sec;

else

return data::operator<(D);

}

};

Ereditarietà vs contenimento

data_con_orario: definita anche senza ereditarietà con campo data.

class data_con_orario {

private:

data D; //contenimento (N.B. data_con_orario NON è sottoclasse di data)

int sec;

public:

...

};

Svantaggi contenimento

1) Ridefinire tutte le funzioni di data, in data_con_orario (quelle che mi servono)

es: int get_anno() { return d.get_anno(); }

2) Non visibili in modo diretto i campi protected della classe data → per i campi datausare

funzioni public (se ad es: avanza_un_giorno() è protected in data, allora non posso scrivere

“...d.avanza_un_giorno()...” )

3) Non sostituibilità: non posso usare data_con_orario al posto di data in una funzione.

f(data d) → con ereditarietà d può essere sia “data” sia “data_con_orario”

Ereditarietà e template

es:

template <class T>

class B {...}; //classe base

class D1: public B <int> {...}; //classe derivata

template classe t>

class D3: public B <t>

Ereditarietà multipla

In c++ una classe può essere derivata da più classi base data → classe derivata ha i campi di tutte le

classi base + i propri.

data ← data_orario → orario

class data_con_orario: public data, public orario {…};

Gerarchia classi - input output in c++

ios <-- istream - ostream

(Es: istream cin)

(Es: ostream cout,cerr)

istream <-- ifstream

ostream <-- ofstream

fstream --> iostream --> istream,ostream

Es: fstream f1;

f1.grum("prova.txt",ios::read)

Programming in the small vs programming in the large

Programming in the small

- PRoblema affrontato da persona singola.

- Codice di dimensioni limitate.

- Metodologie

- Programmazione strutturata.

- Sviluppo top down.

- strumenti linguistici --> astrazione

- dati

- operazioni (funzioni)

- controllo

Programming in the large

- piú persone

- codice di grandi dimensioni

- sistema

- costituito da piú pezzi (moduli) messi insieme in base ad un oppurtuna architettura software

- Moduli sviluppati

- da persone diverse

- in momenti diversi

- Con problemi di progetto

- Metodologie: programmazione modulare

- strumenti linguistici: costrutti per definire moduli e interfaccie. (es: costrutto di classe)

Modello di sviluppo del software (ciclo di vita del software)

Diverse fasi:

1) raccolta e analisi dei requisiti:

- analisi del problema da risolvere

- cosa deve fare?

- in che ambiente?

- interazione con utente finale

Si ricava un documento dei requisiti (o di specifiche del sistema) formale o informale.

- posso produrre manuale utente e altre specifiche.

2) progettazione (o design)

- Individua componenti del sistema (moduli) e le componenti del sistema (architettura).

- Specifica le diverse funzioniofferte da ciascun modulo (interfaccie)

- specifica del comportamento dinamico del sistema: come evolve lo stato.

In fine si ha un prodotto: schemi concettuali di progetto, con:

- appositi formalismi (grafici) --> es:UML unified modeling language (OOD)

3) realizzazione (o codifica o implementazione): realizzazione del sistema tramite linguaggio

programmazione scelto

- codifica per moduli (nel singolo modulo: programming in the small)

- il prodotto é un programma eseguibile e una documentazione

4) verifica:

1) debugging

- eliminazione di errori run-time

2) testing

- prove del programma su dati campione

--> eventuali feedback (ripetere fasi precedenti in caso di errore)

5) manutenzione e revisione sistema

- conseguenza di errori e mal funzionamenti vari

- cambiamenti nelle specifiche

Analisi -> progettazione -> realizzazione -> verifica -> manutenzione

Da questi passaggi, si crea la documentazione.

6) prototipi

...) altre attivitá

- studio fettibilitá (costi benefici - risorse necessarie).

- gestione del progetto (individuare tempi - fasi - allocazione risorse - suddivisione

compiti)

Progettazione / Programmazione modulare.

Modulo: entitá software raggruppa un insieme di dati e operazioni strettamente correlate tra loro

(coesione alta)

Caratteristiche di ciascun modulo

- Autonomo = debolmente connesso con resto del programma (correlazione bassa)

- Relazione con altri moduli definite in modo preciso

- Definizione precisa dei servizi offerti = interfaccia.

- Interfaccia distinta da implementazione = datie funzioni nel modulo non visibili esternamente

(information hiding)

Ciascun modulo

- Unitá di sviluppo se

Dettagli
Publisher
A.A. 2015-2016
63 pagine
SSD Scienze matematiche e informatiche INF/01 Informatica

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher Mr.Al di informazioni apprese con la frequenza delle lezioni di Fondamenti di programmazione e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Università degli Studi di Parma o del prof Scienze matematiche Prof.