Anteprima
Vedrai una selezione di 23 pagine su 106
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 1 Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 2
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 6
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 11
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 16
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 21
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 26
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 31
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 36
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 41
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 46
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 51
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 56
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 61
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 66
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 71
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 76
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 81
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 86
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 91
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 96
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 101
Anteprima di 23 pagg. su 106.
Scarica il documento per vederlo tutto.
Metodologie Programmazione - Tutto (teoria, pratica e esercizi) Pag. 106
1 su 106
D/illustrazione/soddisfatti o rimborsati
Disdici quando
vuoi
Acquista con carta
o PayPal
Scarica i documenti
tutte le volte che vuoi
Estratto del documento

SVOLGIMENTO:

Facciamo prima il diagramma delle classi con ereditarietà:

ZooAnimal <-v-- Beer <--- Panda (schema a diamante)

<-v-- Reccon <---

<--- Endangered <---

ZooAnimal è il primo ad essere costruito.

1) Stampa:

- costuisco ZooAnimal

- costruisco Endengered

- costruisco Beer

- costruisco Reccon

- costruisco Panda

INFO VARIE:

Doxygen genera anche un grafico che indica la gerarchia di classi.

La relazione IS-A permette la conversione in automatico.

- Una ereditarietà pubblica con soli metodi static è fatta per pigrizia cioè è fatta per ereditare senza

doverle riscrivere (mezzo abuso).

qt class diagramm: ogni rettangolo è una classe (la realtà è molto complicata).

http://doc.qt.digia.com/extras/qt43-class-chart.pdf

In questo caso vanno un po' in crisi i principi che abbiamo fatto; qui l'utente può mettersi in lato

astratto o concreto DIPENDE ma in genere in questo caso, serve maggiormente la concretizzazione;

Es: devo fare un programma che chiede agli oggetti come sono tramite dynamic_cast (cose

"negative" in certi contesti ma non in questo).

Gerarchie così complicate sono rivolte a problemi complessi ma se a me interessa solo la parte

concreta, allora non è molto complicato usarle.

Due gerarchie di questa complessità, non sono utilizzabili entrambe contemporaneamente perché

sono fatte per legarvi ad esse (questione di marketing).

PPL - Classe poliedro: si fa subito una suddivisione tra quelli chiusi e quelli che possono essere sia

chiusi che aperti (sui primi, le operazioni sono più veloci); entrambe suddivisioni che fanno parte di

una classe contenente un flag che indica com'è il poliedro.

Qui le proprietà SOLID non valgono ma dato che una modifica difficilmente ci sarà, allora si hanno

degli if-else sparsi nel codice.

Perché usare IS-A e non il contenimento? Potevano farlo ma erano pigri; il poliedro è pesante e

scrivere tutte le funzioni "passa-carte" è noioso.

Dato che la classe base non può essere utilizzata, come facciamo ad obbligare l'utente ad usare una

delle due suddivisioni? Facciamo i costruttori della classe base come protected (utilizzabili solo

dalle derivate ma non dall'esterno).

Design patters: schemi di progettazione generali che indicano problemi che capitano spesso nel

voler creare un progetto complicato.

Frequenti sono (wikipedia):

- I pattern creazionali: nella progettazione con polimorfismo dinamico devi utilizzare astrazioni

ma esiste un punto (tanti punti) nei quali bisogna generare nuovi animali e non si possono costruire

animali astratti quindi si devono anche creare animali concreti.

Questo implica che vi è una dipendenza dall'implementazione.

I partern creazionali gestiscono queste dipendenze mettendole in un unico file "object factory" che

contiene gli oggetti concreti (nel caso della fattoria era maker.cc il quale doveva crearli).

Così è più facile gestire le dipendenze.

Questo però significa che serve anche una factory astratta.

Se devo costruire un pulsante potrei avere due librerie diverse che costruiscono pulsanti in modo

diverso e mi serve quindi una classe astratta per la gestione.

Di oggetto che costruisce il pulsante comunque ne devo avere solo uno e quindi viene gestito anche

questo.

- adapter: adattano tra di loro due interfacce diverse.

- decorator: hai un oggetto pizza che ha anche un costo e gli ingredienti ma questi oggetti vengono

fuori in molti modi diversi; non possiamo immaginarci tutte le possibili combinazioni quindi

consentiamo all'utente durante l'esecuzione di gestire questa cosa consentendo di comporre a

piacere tutte le pizze.

Il decorator è un oggetto che eredita dalla pizza e fornisce un'interfaccia uguale a quella della pizza;

al suo interno si memorizza un riferimento a puntatore che punta ad un'altra pizza; siccome il

metodo che calcola la pizza è overriding, il decorator sovrascrive il metodo per calcolare l'altra

pizza.

Il decorator è una pizza che però si memorizza (sovrascrive) con un'altra pizza cambiando quindi

anche i metodi ad essa legata.

Il decoretor è una pizza (non concreta) nella quale se si aggiunge la mozzarella, io aumento il

prezzo di un certo valore.

Al PC: voglio la finestra con un certo bordo allora creo un decorator che si applica quando creo la

finestra (sono pattern).

- state: registra determinati stati che possono essere utilizzati per cambiare qualcosa.

Uccidi 100 mostri, ricevi una medaglia (la medaglia è un oggetto astratto che dipende dallo stato).

Il numero di ciò che cambia rispetto allo stato, non è fissato.

L'oggetto osservato ha 3 metodi (e una lista):

2 uno per aggiungere e l’altro per togliere alla lista puntatori ad oggetti che osservano lo stato.

1 quando cambia lo stato, l'osservato invoca un metodo (notified) che notifica il proprio

cambiamento agli oggetti della lista. Gli osservanti decideranno poi loro cosa fare.

- visitor: quando la gerarchia è complicata (come quella per gestire le espressioni) dove metto i

virtual?

Se per caso l'utente vuole far fare operazioni diverse e nuove?

Il visitor va ad effettuare controlli (visita) su ad esempio gli animali quindi su gallina, maiale etc

Lato negativo:

- (IL SERVER) Se la nostra astrazione non va più bene quindi se serve una modifica nei metodi,

questo comporta che le classi concrete inventate finora dovranno essere modificate.

- Il visitor va in crisi quando qualcuno aggiunge una nuova classe concreta alla mia gerarchia, il

visitor non sapranno analizzare la nuova classe concreta (in questo caso bisogna quindi aggiornare i

visitor per renderli compatibili con le nuove classi concrete).

FINE info varie.

Costruttori virtuali

Non posso dichiarare virtuali i costruttori perché ho bisogno del this ma il virtual non ha this.

In giro però si trovano costruttori virtuali che però non sono costruttori ma si comportano come tali.

Se io volessi creare una copia concreta di animale che è astratto, come faccio?

Con la costruzione virtuale:

class Anmale {

public:

virtual Animale* clone() const = 0;

};

class Cane : public Animale {

public:

Cane* clone() const { //Se cambia qualcosa nel nome, non vale l'overriding ma qui restituisco un

puntatore Cane e non puntatore ad Animale; questo è possibile se esiste la relazione IS-A (LSP) tra

animale e cane con la quale avviene quindi overriding

return new Cane(*this);

}

}

int main() {

Animale a;

}

- Questo permette di poter costruire un oggetto come prototipo di un altro oggetto (che è il *this).

Es: voglio costruire un sanbernardo:

Costruisco un Animale → Quado costruisco il cane (nasce), voglio che faccia un verso (virtual)... fa

quello del Cane o del Sanbernardo (classe concreta di Cane)?

E’ meglio evitare mettere metodi virtual nei costruttori (o distruttori).

Mentre è proprio sbagliato usare virtual dentro a costruttori (o distruttori) che accedono a dati

dell'oggetto.

Polimorfismo

Esistono 2 forme di polimorfismo:

1) polimorfismo statico (es template):

- Scriviamo degli schemi di funzione con cui generare nuove funzioni.

- Molto più efficienti perché a compilazione sappiamo già chi invocare e possiamo anche

ottimizzare.

- Viene generato molto codice e in certi casi (rari) si peggiorano le prestazioni perché si ha

parecchio codice da caricare in più.

Per risolvere in parte questo problema in certe implementazioni della stl, ci sono operazioni che

valgono per più tipi (vector, liste etc) tramite l’utilizzo di puntatori a qualcosa che sono solo loro a

cambiare (questo soluzione vale anche per il dinamico).

2) polimorfismo dinamico:

- Utilizza classi dinamiche con funzioni astratte perché si decide a tempo di esecuzione cosa farà la

funzione.

- Si fanno più controlli a tempo di esecuzione.

- Si genera meno codice.

Si sta utilizzando maggiormente lo statico (anche perché è meglio intervenire durante la

compilazione).

Es: il fattoriale è meglio farlo durante la compilazione SE si hanno già i dati del fattoriale così si

inserisce il numero ed è più veloce.

Nel linguaggio C++ ci sono molte costanti da scrivere e spesso sono costanti derivate (calcolate) da

altre; nel 2003 non si poteva definire costanti usando altre costanti salvo in casi particolari.

Hanno inventato i const expr: se viene invocata una funzione con dati costanti, si calcolala a tempo

di compilazione e non durante il runtime.

Asserzioni: controlla (solo) durante il debugging e funziona solo a tempo di esecuzione.

Si nota che però certe asserzioni si possono controllare durante la compilazione e quindi si sono

create le static assert:

- se l'asserzione è violata, il programma non compila.

- non c'è distinzione tra compilazione e debugging; tutto il controllo avviene durante la

compilazione.

Si sta quindi creando una separazione ma che comunque non è completa:

Linguaggi molto dinamici: scripting, java, C++ (vecchio)

Linguaggi molto statici: C++

Es: class C {

template <...>

virtual void foo() { … }

}; // NON si può fare in C++

// Il template indica tante possibili funzioni che non possono essere tutte trattate virtualmente

template <...>

class C {

virtual void foo();

} //SI PUÒ fare

// Fissati i valori del template, esiste un solo metodo possibile da trattare come virtual

Multy-Threading e Multy-processing

Supporto alla concorrenza (nuovo, che nel C++ 2003 non esiste)

- Abbiamo sempre ragionato su un singolo flusso di istruzioni (un solo thread):

Program counter (esegue istruzioni), heap (memoria), memoria statica, stack, lista istruzioni etc

- Le macchine moderne hanno più circuiti con tante CPU che possono eseguire più cose

contemporaneamente. Come si può sfruttare questo eccesso di hardware?

1) Multy-processing: ci sono in esecuzione più processi (istanza di un programma in esecuzione; se

ne apro 50, ne avrò 50 uguali che agiscono senza interferire se non lo decido io).

Ogni processo è appunto separato, ma serve un modo per farli interagire.

Per interagire, hanno 2 modalità:

- 1: comunicare attraverso effetti esterni (un processo scrive su un file e un altro processo legge

sullo stesso file).

- 2: chiedere al sistema di avere un blocco di memoria condiviso.

Il fatto che siano indipendenti però è una cosa buona perché si evitano problemi (possono essere

distribuiti più facilmente).

Per farli interagire invece si fatica e si rallenta (più lenti rispetto la situazione ideale).

2) Multy-threading: ho tante

Dettagli
Publisher
A.A. 2015-2016
106 pagine
3 download
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 Metodologie 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.