| 1 | Introduzione al corso. Richiami alle moderne esigenze nella progettazione e produzione del software. L'importanza dell'astrazione e del modello cliente-servitore. Oggetti come centri di servizio. Il cambio del punto di vista. Testi consigliati | Antonio Natali |
| 2 | Un primo progetto. Proposta di un cammino concettuale. Impostazione tradizionale alla progettazione e costruzione del software a partire dalla "macchina". Problema 0: il conteggio delle parole in un file. Necessita' di passare dalla costruzione di "automi risolventi" alla costruzione del software per componenti riusabili e modificabili. | Antonio Natali |
| 3 | Le funzioni come componenti software. Le funzioni come servitori. Trasferimento di argomenti: il meccanismo di trasferimento per riferimento. Funzioni inline. Insufficienza del concetto di funzione. Il ruolo dell'astrazione. Il problema della modifica del software al variare dei requisiti. Problema contare le parole contenute in un file ec visualizzare la (prima) parola più lunga | Antonio Natali |
| 4 | Astrazione e rappresentazione. Astrazioni di dato: principi di base. Tipi di dato astratto (ADT) e loro influenza sul progetto. Astrazione, interfaccia e implementazione: il caso dell'ADT parola. Necessità di mantenere il codice dei clienti indipendente dalla rappresentazione dei dati. Organizzazione modulare del testo del programma attraverso l'uso dei files. ADT e progetto del software: una soluzione al problema1 basata sull'ADT parola. | Antonio Natali |
| 5 | Operazioni, valori, costanti. Una possibile classificazione delle operazioni di un ADT: il punto di vista del cliente. Oggetti come istanze di ADT. Oggetti atomici o composti. Oggetti con o senza stato. Importanza della distinzione tra oggetti come valori e oggetti come contenitori. Protezione dell'informazione nel caso di oggetti intesi come valori. Variabili, assegnamento, r-value ed l-value. Denotazione di oggetti-valore mediante costanti. Costanti in C e C++. | Antonio Natali |
| 6 | Costanti, trasformatori, primitive. Problematiche legate all'uso di costanti in C++. Trasformatori: operazioni che modificano lo stato degli oggetti. Una possibile classificazione delle operazioni di un ADT: il punto di vista di chi realizza. Operazioni dipendenti dalla rappresentazione concreta e operazioni indipendenti dalla rappresentazione (primitive). Problema 2: contare le parole contenute in un file e visualizzarle in un elenco ordinato per lunghezza: una soluzione indipendente dalla rappresentazione. | Antonio Natali |
| 7 | Costruzione di un ADT: l'elenco. Costruzione dell'ADT elenco. Separazione fra interfaccia e rappresentazione. Modifica trasparente della rappresentazione: da una soluzione a memoria statica ad una soluzione basata su memoria dinamica. ADT lista come contenitore di valori. | Antonio Natali |
| 8 | Costruzione di un ADT: la lista. Liste come valori non modificabili: primitive sulle liste di tipo Lisp (cons,first,rest,null). Operazioni sulle liste indipendenti dalla rappresentazione: visualizzazione e inserzione ordinata. La definizione ricorsiva di operazioni come caso-limite di riusabilità. Eliminazione ricorsiva di elementi da una lista priva di trasformatori e analisi del processo a tempo di esecuzione. | Antonio Natali |
| 9 | Astrazione, rappresentazione, moduli. Influenza della rappresentazione sul progetto e sulla struttura del software: il caso delle liste. ADT e organizzazione a moduli dei programmi. Modificabilità dei sistemi organizzati a moduli: il caso dell'elenco di parole. Moduli e componenti software. Realizzazione a moduli di singole astrazioni di dato: il caso del contatore. Limiti di questa impostazione. | Antonio Natali |
| 10 | Classi, istanze, creazione, distruzione. Il concetto di classe come unificazione dei concetti di ADT e di modulo. Protezione dell'informazione: i qualificatori private e public. Esempi di definizione e uso di classi: l'esempio del contatore. Variabili che denotano istanze di classi e loro uso come normali variabili: importanza e conseguenze. Il problema delle costruzione e distruzione delle istanze. Meccanismi impliciti C++ per la costruzione-distruzione di istanze di classi. Il concetto di oggetto - destinatario (sel) e la parola chiave this del C++. | Antonio Natali |
| 11 | Costruttori multipli e costruzione implicita . Operazioni di auto - spiegazione degli oggetti e loro importanza in fase di messa a punto di programmi ad oggetti. Costruttori definiti dall'utente: l'esempio del contatore. Trasferimento di oggetti per valore a funzioni e restituzione di oggetti da parte di funzioni. Trasferimento di oggetti per riferimento. | Antonio Natali |
| 12 | Variabili di classe, puntatori a oggetti. Attributi comuni a istanze di oggetti: variabili di classe (static). Il caso del contatore che tiene traccia del numero delle istanze. Esperimenti e individuazione di un costruttore nascosto. La costruzione di copia e i momenti della sua attivazione. Creazione di oggetti dinamici e relativa distruzione. Operatori new e delete. | Antonio Natali |
| 13 | Oggetti costanti, puntatori, vettori di oggetti. Oggetti costanti e operazioni dichiarate const. Puntatori a oggetti costanti. Array di oggetti. | Antonio Natali |
| 14 | Overloading di operatori, conversioni di tipo . Estensione del linguaggio con tipi di dato definiti dall'utente: l'esempio dell'ADT complex. Il problema della uniformità tra tipi predefiniti e classi definite dall'utente: il caso degli operatori. Overloading degli operatori in C++. Espressioni miste. Costruttori come convertitori di tipo. | Antonio Natali |
| 15 | ADT complex, operazioni friend, operatori di accesso. Espressioni miste complessi-float: non tutto funziona. Superamento del problema mediante operazioni amiche (friend) di una classe. Categorie di oggetti: oggetti come valori e come contenitori. Ridefinizione dell'operator[(come selettore per la classe complex. Selettori e accessi indebiti a oggetti intesi come valori. | Antonio Natali |
| 16 | Oggetti, valori, contenitori: le stringhe. Possibili interpretazioni dell'assegnamento ed eliminazione dell'operator=(X&) dal protocollo di una classe. Oggetti come valori e come enti dotati di stato: il caso dell'ADT stringa. Definizione della classe myString. Una interfaccia funzionale, ispirata al Lisp, per l'uso convenzionale (non a messaggi) di oggetti di tipo myString. | Antonio Natali |
| 17 | Una versione funzionale dell'ADT string. Interfacce funzionali per oggetti-valore della classe myString. Indipendenza del codice dei clienti dalla scelta relativa alla rappresentazione concreta. Transizione da una rappresentazione a memoria statica ad una a memoria dinamica. Ridefinizione dei costruttori, distruttori e dell'operatore di concatenazione (operator+). Influenza della rappresentazione sulla correttezza del software prodotto: il problema dei riferimenti pendenti (dangling references) | Antonio Natali |
| 18 | Oggetti composti, oggetti con puntatori. Classificazione degli oggetti in termini di struttura interna: oggetti semplici, oggetti composti, oggetti con puntatore. Il caso degli oggetti composti: revisione dei meccanismi impliciti di costruzione e distruzione. Esempio: il punto con contatore. Invocazione esplicita di costruttori nella intestazione di un costruttore. Il caso degli oggetti con puntatori: il problema della condivisione delle strutture (structure sharing) e dei riferimenti pendenti (dangling reference). La necessità del costruttore di copia. | Antonio Natali |
| 19 | Il costruttore di copia. Costruzione di copia X(X&) di default in C++ e momenti in cui essa interviene. Definizione esplicita della costruzione di copia in oggetti semplici (esempio del contatore) e composti (esempio del punto). Costruzione di copia in oggetti con puntatori, superamento della copia bit a bit e della condivisione di strutture: il caso delle stringhe basate su memoria dinamica. | Antonio Natali |
| 20 | L'operatore di assegnamento. Assegnamento di default in C++: copia membro a membro (shallow copy) con restituzione di un riferimento all'oggetto destinatario. Frasi ad assegnamento multiplo. Ridefinizione dell'assegnamento da parte dell'utente: le fasi di distruzione e ricostruzione dell'oggetto destinatario. Ridefinizione dell'operator= per la classe myString con copia profonda (deep copy) e superamento dei malfunzionamenti precedenti. | Antonio Natali |
| 21 | Oggetti per l'ingresso/uscita: cin, cout. Il modello ad oggetti: uno strumento per dominare la complessità. Sistemi ad oggetti che includono oggetti predefiniti per l'ingresso/uscita: esempi d'uso. Overloading degli operatori >> e << per gestire le trasformazioni da rappresentazione esterna ad interna e viceversa di oggetti di classi definite dall'utente. | Antonio Natali |
| 22 | Ridefinizione degli operatori << e >>. Ridefinizione degli operatori di uscita ed ingresso per classi di dati definite dall'utente: il caso del contatore e del punto. Introduzione alla problematica della progettazione per il cambiamento. Problema 3: costruire un elenco di parole in cui ciascuna e' riportata una volta sola con a fianco il numero di volte in cui compare nel testo dato. Una (specifica di) soluzione basata sull'astrazione "parola con contatore". | Antonio Natali |
| 23 | Ereditarietà: introduzione. Definizione di classi di dati "alledifferenze": il caso dell'ADT parola rispetto all'ADT myString. I concetti-base della relazione di ereditarietà tra classi. I punti di vista del realizzatore e dell'utente e la dicotomia meccanismo-significato. Struttura e protocollo delle classi derivate. Il problema della visibilitàdelle informazioni all'interno delle classi derivate e il qualificatore protected. La non ereditarietà di costruttori, distruttori e assegnamento. | Antonio Natali |
| 24 | Ereditarietà: costruzione, distruzione . I meccanismi di costruzione-distruzione di default di istanze di classi derivate. Invocazione esplicita di costruttori delle classi-base. L'esempio dell'ADT parola. | Antonio Natali |
| 25 | Ereditarietà, costruzione di copia, assegnamento. I meccanismi impliciti di costruzione di copia nel caso di classi derivate. Ridefinizione del costruttore di copia in una classe derivata e configurazione di campi privati. I meccanismi impliciti di assegnamento nel caso di classi derivate. Ridefinizione dell'assegnamento in una classe derivata, chiamata qualificata e configurazione di campi privati. | Antonio Natali |
| 26 | Ereditarietà e sviluppo incrementale: un esempio. L'ADT parola (con contatore) come classe derivata. Risoluzione del problema 3 usando gli elenchi come liste convenzionali e oggetti di tipo parola. Mancanza di distruzione dell'elenco e delle parole ivi contenute al termine del programma. | Antonio Natali |
| 27 | Ereditarietà e sviluppo incrementale: un elenco di parole (modificabili). Completamento del problema 3 con ingresso da input standard e da file (dispositivodi classe ifstream). Il problema della revisione di operazioni ereditate:il caso della concatenazione di parole. Ereditarietà e modificadei requisiti. Problema 4: scrittura in lettere maiuscole delle parolecon una molteplicità superiore a un valore dato. Definizione di una classe di parole modificabili (modifWord). | Antonio Natali |
| 28 | Ereditarietà e significato: la relazione IS_A. Completamento del problema4. Ereditarietà e significato: ereditarietà public come relazione IS_A. Classi derivate come sottotipi. Introduzione al concetto di polimorfismo. Limiti alla possibilità di realizzare operazioni polimorfiche: il problema del "taglio" degli oggetti trasferiti per copia e i limiti del binding statico. | Antonio Natali |
| 29 | Ereditarietà e polimorfismo. Polimorfismo connesso al trasferimento di oggetti per riferimento e suoi limiti. Il concetto di binding dinamico. Operazioni virtual. Uso dei metodi virtual per realizzare operazioni polimorfiche. Necessità di impostare distruttori virtual. | Antonio Natali |
| 30 | Ereditarietà e polimorfismo: la realizzazione C++. La tabelladei metodi virtuali. Late binding come chiamata indiretta a procedure.Necessità di uso di riferimenti o puntatori ad oggetti per ottenere operazioni polimorfiche. Impossibilità di definire costruttori virtuale regole connesse all'uso di operazioni virtual. Polimorfismo e assegnamento. | Antonio Natali |
| 31 | Ereditarietà IS_LIKE e riuso di codice . Ereditarietà private/protected e visibilità delle informazioni. Riuso del codice attraverso l'ereditarietà private/protected: il caso degli interi non limitati e l'ADT myInt. Il concetto di invariante di classe nel progetto e realizzazione di classi con riferimento alla metodologia di programmazione contrattuale. Ereditarietà private/protected e metodi virtuali. | Antonio Natali |
| 32 | Ereditarietà, progetto e struttura. Ereditarietà, specializzazione e generalizzazione. Uso dell'ereditarietà per separare interfaccia e implementazione: il concetto e il ruolo delle classi astratte. Problema 5: fare l'elenco degli identificatori e delle rappresentazioni dei numeri interi senza segno contenute in un file dato. Impostazione di un progetto basato su una tassonomia di tipi. Una classe astratta PAROLA che sfrutta il late binding per realizzare operazioni indipendenti dalla rappresentazione concreta dei dati. | Antonio Natali |
| 33 | Ereditarietà multipla: introduzione. Completamento del problema 5 con definizione e realizzazione di un semplice analizzatore lessicale. Introduzione alla ereditarietà multipla. Ambiguità delle informazioni e sua risoluzione, derivazioni miste e loro significato. Classi comuni a più percorsi. | Antonio Natali |
| 34 | Ereditarietà multipla: ereditarietà virtual. Il problema delle classi comuni a più percorsi di derivazione. Ereditarietà virtual. Schemi realizzativi della ereditarietà multipla virtual e non. Ereditarietà multipla e puntatori a classi di oggetti. Complessità strutturale e semantica connessa all'ereditarietà multipla: un esempio. Non solo ereditarietà: confronto tra ereditarietà e uso. | Antonio Natali |
| 35 | Classi amiche: una applicazione. Non solo ereditarietà: altre possibili relazioni tra classi. Realizzazione di una lista-contenitore con condivisione di strutture e gestione della memoria. Il ruolo delle classi amiche (friend). Una nuova soluzione al problema 3. Il concetto di iteratore. Uso delle classi friend per realizzare iteratori. Un iteratore per l'ADT myInt della lezione 31.Classi annidate: cenni. | Antonio Natali |
| 36 | Componenti generici: function template. Il problema della costruzione di componenti software generici. Problema 6: costruire elenchi omogenei di oggetti di tipo diverso. Limiti dell'approccio basato sulla ereditarietà (genericità constrained). Il concetto di modello (template). Funzioni generiche: function template e template function. Esempi di uso di function template. Il processo di istanziazione di un modello. | Antonio Natali |
| 37 | Componenti generici: function e class template . Regole per la determinazione (a compile-time) del codice da eseguire in corrispondenza ad una invocazione di funzione. Esempi. Introduzione alle classi generiche: class template e template class. Progetto di modelli ed ipotesi sui parametri che rappresentano tipi. | Antonio Natali |
| 38 | Class template: esempi. Esempi di definizione ed uso di class template. Problematiche di suddivisione delle dichiarazioni e definizioni dei modelli in file diversi. Class template ed ereditarietà. Una lista generica e risoluzione del problema 6. | Antonio Natali |
| 39 | Architetture a oggetti. Messaggi come eventi . Modello ad oggetti, progetto e produzione del software. Architettura statica e a tempo di esecuzione dei programmi. Un caso di studio: determinazione dei numeri primi con il metodo del crivello di Eratostene. Soluzione del problema mediante un sistema a oggetti che si riconfigura dinamicamente. Messaggi: non solo chiamate di procedura. Messaggi come eventi. Il caso di Windows e la Object Windows Library. | Antonio Natali |
| 40 | Librerie di classi. Programmazione ad oggetti ed ambienti di programmazione. Librerie di classi: il caso dei dispositivi di ingresso-uscita. Il concetto di manipolatore e gestione dei manipolatori. Derivazione da ofstream di una nuova classe di dispositivi che inserisce in testa ad ogni linea il valore del contatore dei messaggi emessi. Uso della classe List della libreria 3.1 per la soluzione del problema 6. Cenni a direzioni di sviluppo del C++: le eccezioni nell'ambito della programmazione contrattuale. | Antonio Natali |