Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione...

60
1 A.A. 2012/2013 Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia Fondamenti di Programmazione Ingegneria dellAutomazione Industriale Ingegneria Elettronica e delle Comunicazioni Alessandro Saetti & Marco Sechi (email: {saetti,marco.sechi}@ing.unibs.it) Università degli Studi di Brescia A.A. 2012/2013

Transcript of Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione...

Page 1: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

1A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Fondamenti di ProgrammazioneIngegneria dell’Automazione Industriale

Ingegneria Elettronica e delle Comunicazioni

Alessandro Saetti& Marco Sechi

(email: {saetti,marco.sechi}@ing.unibs.it)

Università degli Studi di BresciaA.A. 2012/2013

Page 2: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

2A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizi sulle classi (1º parte)1. Definire la classe delle date del calendario con

– Un costruttore che inizializzi la data al capodanno del 2000;– Un metodo che inizializzi la data con tre interi acquisiti da tastiera;– Un metodo che visualizzi la data;– Un metodo che faccia avanzare la data di una giornata.

Scrivere un programma C++ che, sfruttando la classe precedentemente definita, inizializzi la data con tre interi acquisiti da tastiera, faccia avanzare la data di 15 giorni ed infine visualizzi la data risultante.

Page 3: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

3A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizi sulle classi (1º parte)2. Definire la classe dei numeri complessi con

• Un costruttore che inizializzi il numero complesso rappresentato con dati acquisiti da tastiera;

• Un costruttore che inizializzi il numero complesso con una data parte reale ed una data parte immaginaria;

• Un metodo che produca un numero complesso ottenuto incrementando un dato numero complesso con il numero complesso della classe;

• Un metodo che visualizzi il numero complesso nella forma “x + yi” (“x - yi” se y è negativo).

Scrivere un programma C++ che, sfruttando la classe precedentemente definita, inizializzi un numero complesso con dati acquisiti da tastiera, incrementi il numero complesso acquisito con il numero complesso 3.5 – 4i, ed infine visualizzi il numero complesso risultante.

Page 4: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

4A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Definire la classe delle date del calendario con– Un costruttore che inizializzi la data al capodanno del 2000;– Un metodo che inizializzi la data con tre interi acquisiti da tastiera;– Un metodo che visualizzi la data;– Un metodo che faccia avanzare la data di una giornata.

Scrivere un programma C++ che, sfruttando la classe precedentemente definita, inizializzi la data con tre interi acquisiti da tastiera, faccia avanzare la data di 15 giorni ed infine visualizzi la data risultante.

Page 5: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

5A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Esercizi sulle classi (1°parte)

/*************************************************************************** Nome: casa1-data.c ** Autore: Alessandro Saetti ** Data: 6/4/10 ***************************************************************************/

#include <iostream>#include <stdlib.h>

/* Nome: main* Scopo: Gestione delle date* Input: -* Output: 0 se il programma termina correttamente*/

int main() {

system("pause");return 0;

}

Impostiamo la solita struttura iniziale  di un programma C, aggiungendo eventuali commenti

// Definizione classe

Definire la classe delle date del calendario con–Un costruttore che inizializzi la data al capodanno del 2000;–Un metodo che inizializzi la data con tre interi acquisiti da tastiera;–Un metodo che visualizzi la data;–Un metodo che faccia avanzare la data di una giornata.

Scrivere un programma C++ che, sfruttando la classe precedentemente definita, inizializzi la data con tre interi acquisiti da tastiera, faccia avanzare la data di 15 giorni ed infine visualizzi la data risultante.

// Utilizzo della classe

Per la gestione dell’I/O utilizzeremo gli oggetti globali di I/O cin e cout abbinati agli operatori di flusso << e >> per cui Includiamo <iostream>

Page 6: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

6A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Esercizi sulle classi (1°parte)

Iniziamo ad impostare la definizione per la classe Data.

Definire la classe delle date del calendario con–Un costruttore che inizializzi la data al capodanno del 2000;–Un metodo che inizializzi la data con tre interi acquisiti da tastiera;–Un metodo che visualizzi la data;–Un metodo che faccia avanzare la data di una giornata.

Scrivere un programma C++ che, sfruttando la classe precedentemente definita, inizializzi la data con tre interi acquisiti da tastiera, faccia avanzare la data di 15 giorni ed infine visualizzi la data risultante.

class Data{

public:Data()

private:int aa, mm, gg;

};

/* Nome: Data::Data* Scopo: Costruttore di default della classe Data* Input: -* Output: -*/

Data::Data() {

gg = mm = 1;aa = 2000;

}

Implementiamo il costruttore di default (esternamente alla classe)

// l’operatore binario di risoluzione di visibilità// :: “qualifica” l’appartenenza alla classe

// Costruttore di default

// Dati membro o attributi

Ricordiamoci che per il costruttore nonsi deve dichiarare alcun valore di ritorno

Page 7: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

7A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Esercizi sulle classi (1°parte)Definire la classe delle date del calendario con

–Un costruttore che inizializzi la data al capodanno del 2000;–Un metodo che inizializzi la data con tre interi acquisiti da tastiera;–Un metodo che visualizzi la data;–Un metodo che faccia avanzare la data di una giornata.

Scrivere un programma C++ che, sfruttando la classe precedentemente definita, inizializzi la data con tre interi acquisiti da tastiera, faccia avanzare la data di 15 giorni ed infine visualizzi la data risultante.

void Data::acquisisci() {

cout << "Inserisci giorno: ";cin >> gg;cout << "Inserisci mese: ";cin >> mm;cout << "Inserisci anno: ";cin >> aa;

}

class Data{

public:Data()void acquisisci();

private:int aa, mm, gg;

};

Ricordiamoci di inserire il tiporestituito dalla funzione‐membro della classe (anche se void)

#include <iostream>…using namespace std;

Implementiamo, all’esterno della definizione della classe, la funzione membro acquisisci()

Inseriamo l'istruzione "using namespace std" ("using‐directive"). Con essa si rendono accessibili tutti i membri del namespace std senza doverli qualificare ad ogni chiamata mediante l'operatore di risoluzione dello scope ::. Pertanto gli oggetti globali di I/O std::cin e std::cout potranno essere richiamati semplicemente con cin e cout.

Aggiungiamo alla definizione della classe la dichiarazione della funzione‐membro acquisisci()

Per la gestione dell’I/O utilizziamo gli oggetti globali di I/O cin e cout abbinati agli operatori di flusso << e >>.

Per la gestione dell’I/O utilizziamo gli oggetti globali di I/O cin e cout abbinati agli operatori di flusso << e >>.

Page 8: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

8A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Esercizi sulle classi (1°parte)

Aggiungiamo alla definizione della classe la dichiarazione della funzione‐membro stampa() ricordandoci di aggiungere il tipo restituito

Definire la classe delle date del calendario con–Un costruttore che inizializzi la data al capodanno del 2000;–Un metodo che inizializzi la data con tre interi acquisiti da tastiera;–Un metodo che visualizzi la data;–Un metodo che faccia avanzare la data di una giornata.

Scrivere un programma C++ che, sfruttando la classe precedentemente definita, inizializzi la data con tre interi acquisiti da tastiera, faccia avanzare la data di 15 giorni ed infine visualizzi la data risultante.

/* Nome: Data::stampa* Scopo: Stampa la data* Input: -* Output: -*/

void Data::stampa(){

cout << gg << "/" << mm << "/" << aa << endl;}

class Data{

public:Data()void acquisisci();void stampa();

private:int aa, mm, gg;

};

Implementiamo, esternamente alla classe, la funzione membro stampa() che mostra a video la data 

Page 9: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

9A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Esercizi sulle classi (1°parte)

Data::Data(){

aa=2000;gg=mm=1;

}

void Data::Acquisisci() {

cout << "Inserisci giorno: ";cin >> gg;cout << "Inserisci mese: ";cin >> mm;cout << "Inserisci anno: ";cin >> aa;

}

void Data::Stampa(){

cout << gg << "/" << mm << "/“ << aa << endl;}

Inventiamoci quindi un main() che ci consenta di testare tutte le funzionalità fino a questo punto implementate

int main(){

Data d;d.stampa();d.acquisisci();d.stampa();

}

#include <iostream>using namespace std;

class Data{

public:Data(); void acquisisci();void avanza();void stampa();

private:int aa, mm, gg;

};

Prima di proseguire possiamo testare il programma che abbiamo implementato fino a questo punto.

Page 10: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

10A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Esercizi sulle classi (1°parte)Definire la classe delle date del calendario con

–Un costruttore che inizializzi la data al capodanno del 2000;–Un metodo che inizializzi la data con tre interi acquisiti da tastiera;–Un metodo che visualizzi la data;–Un metodo che faccia avanzare la data di una giornata.

Scrivere un programma C++ che, sfruttando la classe precedentemente definita, inizializzi la data con tre interi acquisiti da tastiera, faccia avanzare la data di 15 giorni ed infine visualizzi la data risultante.

void Data::Avanza(){

gg++; // incremento il giorno

// 1) Calcolo l’ultimo giorno// del mese indicato in mm

// 2) se gg è maggiore dell’ultimo// giorno del mese pongo gg = 1 // ed incremento mm di uno

// 3) se mm>12 incremento l’anno// e pongo mm=1

}

( ((aa % 400)==0) || ( ((aa % 4)==0) && ((aa % 100)!=0) ) )

Per determinare l’ultimo giorno di ogni mese devo disporre di un elenco contenente tale valore distinto per mese. Il seguente array potrebbe essere adatto ai nostri scopi:int v[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

Occorre però tener conto che febbraio, negli anni bisestili, ha 29 giorni. Un anno è bisestoquando è multiplo di 400 oppure se è divisibile per 4 ma non per 100. La condizione sottostante consente quindi di valutare se un anno aa è bisestile o meno:

. . . e poi procedo, se necessario,  con opportune correzioni (Normalizzazione).

// CORREGGO SE GG NON E’ SENSATO

Per passare al giorno successivoincremento la variabile gg di 1 …

Page 11: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

11A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Esercizi sulle classi (1°parte)

#define TRUE 1#define FALSE 0. . ./* Nome: Data::bisestile* Scopo: Determina se l'anno della data e' bisestile* Input: -* Output: TRUE, se l'anno e' bisestile* FALSE, altrimenti*/

int Data::bisestile() {if (aa % 4 == 0 && aa % 100 != 0 || aa % 400 == 0)

return TRUE;return FALSE;

}

Per determinare se è un anno bisestile definiamo la funzione‐membro privata sottostante:

/* Nome: Data::giorni* Scopo: Restituisce il numero di giorni in un mese* Input: int mese: il mese da esaminare* Output: il numero di giorni di mese*/

int Data::giorni(int mese) {int v[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};if (mese == 2 && bisestile())

return 29; else

return v[mese-1];}

Mentre per  determinare l’ultimo giorno del mese definiamo questa funzione‐membro privata:

Se mese==2 ed aa è bisestile allora i giornisono 29 altrimenti sono v[mese‐1]

void Data::Avanza(){

gg++;

// 1) Calcolo l’ultimo giorno // del mese indicato in mm

// 2) . . .

// 3) . . . }

Inseriamo le due #define TRUE e FALSE per rendere più leggibile il codice della funzione‐membro bisestile()

Page 12: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

12A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Esercizi sulle classi (1°parte)

class Data{

public:Data();void acquisisci();void avanza();void stampa();

private:int aa, mm, gg;int bisestile();int giorni ();

};

le due funzioni membro bisestile() e giorni()sono destinate ad uso interno per la classe per cui le aggiungiamo alla sezione private:. La funzione‐membro avanza() , che deve essere usata nel main(), verrà posta nella sezione public:

void Data::Avanza(){

gg++; // incremento il giorno// 1) Calcolo il nr di giorni // del mese indicato in mm

// 2) se gg è maggiore dell’ultimo// giorno del mese pongo gg = 1 // ed incremento mm di uno

// 3) se mm>12 incremento l’anno// e pongo mm=1

}

Continuiamo con l’implementazione della funzione‐membro avanza()

if (gg > giorni(mm)) {gg = 1;mm++;

}

if (mm > 12) {mm = 1;aa++;

}

Aggiorniamo la definizione della classe Data:

Page 13: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

13A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Esercizi sulle classi (1°parte)

Possiamo inserire le istruzioni utilizzate per  la “normalizzazione” della variabile gg all’interno di una funzione‐membro privata che chiameremo normalizza():

Mentre l’implementazione della funzione‐membro avanza() che utilizza la nuova funzione‐membro normalizza() diventa:

/* Nome: Data::normalizza* Scopo: Normalizza la data* Input: -* Output: -* Note: Suppone che i giorni della data eccedano al* piu' di una unita' il numero di giorni possibili*/

void Data::normalizza() {if (gg > giorni(mm)) {

gg = 1;mm++;

} if (mm > 12) {

mm = 1;aa++;

}}

/* Nome: Data::avanza* Scopo: Incrementa la data * corrente di un giorno* Input: -* Output: -*/

void Data::avanza() {

gg++;normalizza();

}

class Data{

public:Data();void acquisisci();void avanza();void stampa();

private:int aa, mm, gg;bool bisestile();int giorni ();void normalizza();

};

Completiamo la definizione della classe Datainserendo nella sezione private: la dichiarazione 

della funzione‐membro normalizza():

Page 14: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

14A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Esercizi sulle classi (1°parte)

Definire la classe delle date del calendario con–Un costruttore che inizializzi la data al capodanno del 2000;–Un metodo che inizializzi la data con tre interi acquisiti da tastiera;–Un metodo che visualizzi la data;–Un metodo che faccia avanzare la data di una giornata.

Scrivere un programma C++ che, sfruttando la classe precedentemente definita, inizializzi la data con tre interi acquisiti da tastiera, faccia avanzare la data di 15 giorni ed infine visualizzi la data risultante.

int main() {

Data oggi;int i;

oggi.acquisisci();for (i = 0; i < 15; i++)

oggi.avanza();cout << "Data dopo 15 giorni: ";oggi.stampa();

system("pause");return 0;

}

Sfruttando la classe Data e le sue funzioni‐membro possiamo ora implementare il nostro main()

Acquisisco una data

Avanzo di 15 giorni tramite un ciclo for

Stampo la data

Page 15: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

15A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Esercizi sull’uso delle classi (1°parte)Soluzione completa …

/*************************************************************************** Nome: casa1-data.c ** Autore: Alessandro Saetti ** Data: 6/4/10 ***************************************************************************/

#include <iostream>#include <stdlib.h>#define TRUE 1#define FALSE 0using namespace std;class Data {

public:Data();void acquisisci();void stampa();void avanza();

private:int gg, mm, aa;int bisestile();int giorni(int mese);void normalizza();

};

Page 16: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

16A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Esercizi sull’uso delle classi (1°parte)

.. soluzione completa …/* Nome: Data::Data* Scopo: Costruttore di default della classe Data* Input: -* Output: -*/

Data::Data() {gg = mm = 1;aa = 2000;

}/* Nome: Data::acqusisci* Scopo: Inizializzazione della data con interi acquisiti da tastiera* Input: -* Output: -*/

void Data::acquisisci() {cout << "Inserisci giorno: ";cin >> gg;cout << "Inserisci mese: ";cin >> mm;cout << "Inserisci anno: ";cin >> aa;

}

Page 17: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

17A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Esercizi sull’uso delle classi (1°parte).. soluzione completa …

/* Nome: Data::stampa* Scopo: Stampa la data* Input: -* Output: -*/

void Data::stampa() {cout << gg << "/" << mm << "/" << aa << endl;

}/* Nome: Data::avanza* Scopo: Incrementa la data corrente di un giorno* Input: -* Output: -*/

void Data::avanza() {gg++;normalizza();

}/* Nome: Data::bisestile* Scopo: Determina se l'anno della data e' bisestile* Input: -* Output: TRUE, se l'anno e' bisestile* FALSE, altrimenti*/

Page 18: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

18A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Esercizi sull’uso delle classi (1°parte).. soluzione completa …

int Data::bisestile() {if (aa % 4 == 0 && aa % 100 != 0 || aa % 400 == 0)

return TRUE;return FALSE;

}/* Nome: Data::giorni* Scopo: Restituisce il numero di giorni in un mese* Input: int mese: il mese da esaminare* Output: il numero di giorni di mese*/

int Data::giorni(int mese) {int v[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};if (mese == 2 && bisestile())

return 29; else

return v[mese-1];}/* Nome: Data::normalizza* Scopo: Normalizza la data* Input: -* Output: -* Note: Suppone che i giorni della data eccedano al piu' di * una unita' il numero di giorni possibili */

Page 19: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

19A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 1Esercizi sull’uso delle classi (1°parte).. soluzione completa.

void Data::normalizza() {if (gg > giorni(mm)) {

gg = 1;mm++;

} if (mm > 12) {

mm = 1;aa++;

}}/* Nome: main* Scopo: Gestione delle date* Input: -* Output: 0 se il programma * termina correttamente*/

int main() {

Data oggi;int i;oggi.acquisisci();for (i = 0; i < 15; i++)

oggi.avanza();cout << "Data dopo 15 giorni: ";oggi.stampa();system("pause");return 0;

}

Page 20: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

20A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2Definire la classe dei numeri complessi con• Un costruttore che inizializzi il numero complesso rappresentato con dati

acquisiti da tastiera;• Un costruttore che inizializzi il numero complesso con una data parte reale ed

una data parte immaginaria;• Un metodo che produca un numero complesso ottenuto incrementando un dato

numero complesso con il numero complesso della classe;• Un metodo che visualizzi il numero complesso nella forma “x + yi” (“x - yi”

se y è negativo).Scrivere un programma C++ che, sfruttando la classe precedentemente

definita, inizializzi un numero complesso con dati acquisiti da tastiera, incrementi il numero complesso acquisito con il numero complesso 3.5 – 4i, ed infine visualizzi il numero complesso risultante.

Page 21: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

21A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2Esercizi sulle classi (1°parte)

/*************************************************************************** Nome: lab1-complesso.c ** Autore: Alessandro Saetti ** Data: 6/4/10 ***************************************************************************/

#include <iostream>#include <stdlib.h>

/* Nome: main* Scopo: Gestione dei numeri complessi* Input: -* Output: 0 se il programma termina correttamente*/

int main() {

system("pause");return 0;

}

Impostiamo la solita struttura iniziale  di un programma C, aggiungendo eventuali commenti

// Definizione classe

Definire la classe dei numeri complessi con•Un costruttore che inizializzi il numero complesso rappresentato con dati acquisiti da tastiera;•Un costruttore che inizializzi il numero complesso con una data parte reale ed una data parte immaginaria;•Un metodo che produca un numeri complesso ottenuto incrementando un dato numero complesso con il numero complesso della classe;

•Un metodo che visualizzi il numero complesso nella forma  “x + yi” (“x ‐ yi” se y è negativo).Scrivere un programma C++ che, sfruttando la classe precedentemente definita, inizializzi un numero complesso con dati acquisiti da tastiera, incrementi il numero complesso acquisito con il numero complesso 3.5 – 4i, ed infine visualizzi il numero complesso risultante.

// Utilizzo della classe

Page 22: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

22A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2Esercizi sulle classi (1°parte)

/* Nome: Complesso* Scopo: Inizializza il numero

complesso con numeri acquisiti da tastiera

* Input: -* Output: -*/

Complesso::Complesso() {

cout << "Parte reale: ";cin >> reale;cout << "Parte immaginaria: "; cin >> immag;

}

Implementiamo il costruttore di default (quello senza argomenti)

Definire la classe dei numeri complessi con•Un costruttore che inizializzi il numero complesso rappresentato con dati acquisiti da tastiera;•Un costruttore che inizializzi il numero complesso con una data parte reale ed una data parte immaginaria;•Un metodo che produca un numeri complesso ottenuto incrementando un dato numero complesso con il numero complesso della classe;

•Un metodo che visualizzi il numero complesso nella forma  “x + yi” (“x ‐ yi” se y è negativo).Scrivere un programma C++ che, sfruttando la classe precedentemente definita, inizializzi un numero complesso con dati acquisiti da tastiera, incrementi il numero complesso acquisito con il numero complesso 3.5 – 4i, ed infine visualizzi il numero complesso risultante.

/* Nome: Complesso::Complesso* Scopo: Costruttore alternativo della * classe complesso* Input: float r: la parte reale del* numero complesso* float i: la parte immaginaria* del numero complesso* Output: -*/

Complesso::Complesso(float r, float i) {

reale = r;immag = i;

}

... e il secondo costruttore, in overloading, distinto per la differente  lista di argomenti

Page 23: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

23A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2Esercizi sulle classi (1°parte)

/* Nome: Complesso::somma* Scopo: Somma un numero complesso al numero complesso rappresentato * dall'oggetto* Input: Complesso addendo: il numero complesso da sommare* Output: Restituisce la somma tra i due* numeri complessi*/

Complesso Complesso::somma(Complesso addendo) {return Complesso (reale + addendo.reale, immag + addendo.immag);

}

Implementiamo la funzione membro somma() che aggiunge al numero complesso della classe il complesso passato come addendo …

Definire la classe dei numeri complessi con•Un costruttore che inizializzi il numero complesso rappresentato con dati acquisiti da tastiera;•Un costruttore che inizializzi il numero complesso con una data parte reale ed una data parte immaginaria;•Un metodo che produca un numeri complesso ottenuto incrementando un dato numero complesso con il numero complesso della classe;

•Un metodo che visualizzi il numero complesso nella forma  “x + yi” (“x ‐ yi” se y è negativo).Scrivere un programma C++ che, sfruttando la classe precedentemente definita, inizializzi un numero complesso con dati acquisiti da tastiera, incrementi il numero complesso acquisito con il numero complesso 3.5 – 4i, ed infine visualizzi il numero complesso risultante.

void Complesso::stampa() {if ( (reale!=0) || (immag==0) )

cout << reale;if (immag!=0) {

if ((immag > 0) && (reale!=0)) cout << "+";if (immag!=1) cout << immag;

cout << "i";}

}

… e successivamente quella che stampa a video il numero complesso

Page 24: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

24A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2Esercizi sulle classi (1°parte)

class Complesso {public:

Complesso();Complesso(float r, float i);Complesso somma(Complesso addendo);void stampa();

private:float reale, immag;

};

Definiamo quindi la classe Complesso.

Definire la classe dei numeri complessi con•Un costruttore che inizializzi il numero complesso rappresentato con dati acquisiti da tastiera;•Un costruttore che inizializzi il numero complesso con una data parte reale ed una data parte immaginaria;•Un metodo che produca un numeri complesso ottenuto incrementando un dato numero complesso con il numero complesso della classe;

•Un metodo che visualizzi il numero complesso nella forma  “x + yi” (“x ‐ yi” se y è negativo).Scrivere un programma C++ che, sfruttando la classe precedentemente definita, inizializzi un numero complesso con dati acquisiti da tastiera, incrementi il numero complesso acquisito con il numero complesso 3.5 – 4i, ed infine visualizzi il numero complesso risultante.

Ricordiamoci di inserire, per ogni singola funzione‐membro, il tipo di dato restituito

Sfruttando la classe Complesso e le sue funzioni‐membro possiamo implementare ora il main():

int main() {Complesso n1, n2(3.5, 4);n1.stampa();n1 = n1.somma(n2);cout << " + ";n2.stampa();cout << " = ";n1.stampa();cout << endl;system("pause");return 0;

}

Definiamo due istanze della classe Complesso: n1 e n2.

Stampo n1 e poi lo incremento di n2

Stampo n2 e il nuovo valore di n1

Page 25: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

25A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2Esercizi sull’uso delle classi (1°parte)Soluzione completa …

/*************************************************************************** Nome: lab1-complesso.c ** Autore: Alessandro Saetti ** Data: 6/4/10 ***************************************************************************/

#include <iostream>#include <stdlib.h>using namespace std;class Complesso {public:

Complesso(float r, float i);Complesso();Complesso somma(Complesso addendo);void stampa();

private:float reale, immag;

};/* Nome: Complesso* Scopo: Inizializza il numero complesso con numeri acquisiti da tastiera* Input: -* Output: -*/

Page 26: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

26A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2Esercizi sull’uso delle classi (1°parte)… soluzione completa …

Complesso::Complesso() {cout << "Parte reale: ";cin >> reale;cout << "Parte immaginaria: "; cin >> immag;

}/* Nome: Complesso::Complesso* Scopo: Costruttore alternativo della classe complesso* Input: float r: la parte reale del numero complesso* float i: la parte immaginaria del numero complesso* Output: -*/

Complesso::Complesso(float r, float i) {reale = r;immag = i;

} /* Nome: Complesso::somma* Scopo: Somma un numero complesso al numero complesso rappresentato * dall'oggetto* Input: Complesso addendo: il numero complesso da sommare* Output: Restituisce la somma tra i due numeri complessi*/

Page 27: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

27A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2Esercizi sull’uso delle classi (1°parte)… soluzione completa …

Complesso Complesso::somma(Complesso addendo) {return Complesso (reale + addendo.reale, immag + addendo.immag);

}/* Nome: Complesso::stampa* Scopo: Stampa il numero complesso * Input: -* Output: -*/

void Complesso::stampa() {if ( (reale!=0) || (immag==0) )

cout << reale;if (immag!=0) {

if ((immag > 0) && (reale!=0)) cout << "+";if (immag!=1) cout << immag;

cout << "i";}

}/* Nome: main* Scopo: Gestione dei numeri complessi* Input: -* Output: 0 se il programma termina correttamente*/

Page 28: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

28A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2Esercizi sull’uso delle classi (1°parte)… soluzione completa.

int main() {

Complesso n1, n2(3.5, 4);n1.stampa();n1 = n1.somma(n2);cout << " + ";n2.stampa();cout << " = ";n1.stampa();cout << endl;system("pause");return 0;

}

Page 29: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

29A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 – Soluzione alternativaEsercizi sulle classi (1°parte)

Vediamo come possiamo implementare la soluzione dell’esercizio 2 sfruttando l’overload degli operatori.

OVERLOAD DEGLI OPERATORI

Prima di procedere ricordiamo che una famiglia di funzioni aventi lo stesso nome, ma un diverso set di argomenti (signature), è detta in rapporto di overloading, o sovraccaricata. 

L’ overloading , oltre alle funzioni, può essere applicato ai costruttori e agli operatori. 

Illustriamo ora brevemente la tecnica di overload degli operatori.

Esercizio 2 – Soluzione alternativa

Page 30: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

30A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Overload degli operatoriEsercizi sulle classi (1°parte)

Overload degli operatori…In C++ sono definiti dei tipi nativi (esempio: int, char, float, double ...) sui quali è possibile applicare  un insieme di operazioni convenzionali (rappresentate da simboli come +, * , / , etc…)

Non sempre la realtà  può essere rappresentata mediante i tipi nativi (si pensi a: numeri complessi, matrici, aggregazioni di dati, etc...) ma occorre fare ricorso a tipi astratti come ad esempio le classi.La semantica delle operazioni applicabili a tali tipi astratti potrebbe differire da quella comunemente associata ai simboli convenzionali per cui nasce la necessità di ridefinirne il significato.

Operazione di somma intesa come unione

Ad esempio il simbolo + può assumere significati diversi a seconda del tipo di dato trattato. Prendiamo ad esempio queste operazioni di “addizione”:

Operazione di somma applicata alle matrici

Il C++ permette di ridefinire il significato di un simbolo convenzionale rendendolo adatto al tipo astratto definito dal programmatore. La tecnica che consente questo è l’overload degli operatori

L’uso del simbolo convenzionale per richiamare le operazioni definite in una classe permette una notazione più compatta che evita chiamate a funzioni specifiche che rendono meno leggibile il codice.

Page 31: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

31A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Overload degli operatoriEsercizi sulle classi (1°parte)

Overload degli operatori…

Operazione espressa consimboli convenzionali

Operazione implementata mediantechiamate a funzioni specifiche.

Y=A+B*C

Y=SOMMA(A,MOLTIPLICA(B,C))

Nell’esempio sottostante l’immediatezza della formula, quando utilizzo gli operatori + e * rispetto a quella che usa le funzioni somma() e moltiplica(), è evidente :

Per ottenere l'overload di un operatore bisogna creare una funzione il cui nome deve essere costituito dalla parola‐chiave operator seguita, con o senza blank, dal simbolo dell'operatore sovraccaricato (ad esempio: operator+). Gli argomenti della funzione corrispondono agli operandi dell’operatore.

tipo-restituito operatorOPERATORE (lista-argomenti)

La ridefinizione di un operatore deve essere la più vicina possibile al senso che l’operatore ha per i tipi nativi.  Anche se è possibile definire in modo arbitrario ciò che fa un operatore si crea solo confusione quando questo determina una semantica inaspettata (si immagini una ridefinizione dell’operatore + che effettua un’operazione simile ad una sottrazione)

Page 32: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

32A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Overload degli operatoriEsercizi sulle classi (1°parte)

E' possibile effettuare l'overloading degli operatori mediante funzioni‐membro della classe stessa. In questo caso l’oggetto chiamante coincide con il primo operando. Segue che le funzioni‐membro associate ad un operatore binario abbiano un solo parametro (corrispondente al right‐operand) mentre quelle relative ad operatori unari nessuno.

Vettore*Scalare Scalare*Vettore

Supponiamo di aver definito la classe Vettore2D e di voler implementare l’overload dell’operatore “*” in modo che abbiano significato le due operazioni:

… overload degli operatori …

L’overloading mediante funzioni‐membro non è sempre attuabile. Infatti questa modalità implica che l’operando a sinistra debba essere un membro della classe ma questo non  sempre possibile (si pensi alla somma tra un numero reale e uno immaginario oppure agli operatori di flusso >> e <<). Ecco un esempio:

Il prodotto di uno scalare per un vettore

class MyClass {...

MyClass operator+(MyClass);MyClass operator++(); // prefissaMyClass operator--(int notused); // suffissa

...};

main() {...

C=A+B // oppure C=A.operator+(B);++C // oppure C.operator++();C-- // oppure C.operator++(1);

...}

++, ‐‐ : operatori unari

+ : operatore binario

In entrambi i casi l’overload dell’operatore deve restituire un oggetto della classe Vettore2D. Nel primo caso il left‐operand Vettore appartiene alla classe Vettore2D e quindi la funzione‐operatore può essere funzione membro della classe stessa. Nel secondo caso il primo operando non appartiene alla classe Vettore2D e pertanto la funzione‐operatore deve essere esterna alla classe Vettore2D :

C=A+B; è equivalente aC=A.operator+(B);

Con l’overloading dell’operatore la chiamata della  funzione "scompare" dal codice del programma e al suo posto viene usata una più "semplice e concisa rappresentazione“ costituita dal simbolo convenzionale associato all’operazione.

Page 33: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

33A.A. 2012/2013

Vettore2D operator*(float a, Vettore2D B) {

return Vettore2D (a*B.x, a*B.y); }

Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Overload degli operatoriEsercizi sulle classi (1°parte)

… overload degli operatori

int main() {

Vettore2D P;Vettore2D A(4.2,4);P = A * 3; // oppure A.operator*(3);... // Istruzioni di di outputP = 3 * A;... // Istruzioni di di output

}

Ecco un main() di esempio che utilizza la classe Vettore2D

class Vettore2D {public:

Vettore2D();Vettore2D(float r, float i);Vettore2D operator*(float);friend Vettore2D operator*(float,Vettore2D);...

private:float x, y;

};

Vettore2D Vettore2D::operator*(float b) {

return Vettore2D (x*b, y*b ); }

Overloading mediante una funzione esterna alla classe

Una funzione friend in una classe ha accesso ai  membri privati della classe pur non essendone  membro

Overloading mediante una funzione membro

Vettore2D::Vettore2D(float a, float b) {

x = a;y = b;

}

Vettore2D::Vettore2D() {

x = 0;y = 0;

}

CostruttoriImplementazione della classe di esempio Vettore2D:

Esempio di esecuzione

senza friend i membri privati x e ydi B non risulterebbero accessibili!

Page 34: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

34A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Overload degli operatoriEsercizi sulle classi (1°parte)

• Gli operatori per i quali è ammesso l’overload sono: Alcune precisazioni utili relative all’overload degli operatori

• Gli operatori per i quali non è ammesso l’overload sono: . :: .* ?: sizeof typeid• Non si può ridefinire un operatore che opera su i tipi nativi (int, char, float,…) poiché questi non sono ne classi ne strutture. Quindi la ridefinzione int operator+(int, int); non è permessa

• Non si può cambiare l’arità (numero di operandi) di un operatore e neppure la sua associatività• Non è concesso "inventare" nuovi simboli, ma si devono utilizzare solo quelli degli operatori esistenti.  • Le regole di precedenza restano legate al simbolo e non dipendono dal nuovo significato che l’operatore ha assunto con l’overloading (ad esempio l’operatore * avrà sempre precedenza sul +).

• E’ possibile ridefinire più volte lo stesso operatore e l'ambiguità, come nel caso delle funzioni, viene risolta in base al contesto degli operandi, riconoscendone il tipo e decidendo di conseguenza quale definizione operatore applicare. 

• Un operatore unario può essere ridefinito come funzione membro senza argomenti oppure come funzione non membro con un argomento. Analogamente un operatore binario può essere ridefinito come funzione membro con un argomento oppure come funzione non membro con due argomenti

• gli argomenti‐operandi sono generalmente passati by reference e dichiarati const, per maggiore sicurezza (const) e rapidità di esecuzione (passaggio by reference);

• L’overload deve essere esplicito: fare l’overload di = non condiziona +=, ‐= o !=

Page 35: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

35A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Overload degli operatori di flussoEsercizi sulle classi (1°parte)

Overload degli operatori di flusso << e >> …Prima di procedere con l’overload degli operatori di flusso analizziamo la gestione dell’I/O implementata nella libreria iostream del C++.

La libreria iostream del C++ mette a disposizione un insieme di classi, funzioni ed oggetti globali per l'esecuzione delle operazioni di input‐output. E’ in questa libreria che sono definiti gli oggetti globali di I/O cout, cerr e cin e che risultano collegati ai dispositivi standard di I/O stdout, stderr e stdin. Per utilizzare questi cout, cerr e cin occorre includere l'header‐file: <iostream>.

Nella libreria iostream le operazioni di I/O vengono gestite in modo indipendente dal dispositivo effettivamente utilizzato  e che può essere un device fisico, un file o un’area di memoria come ad esempio una stringa.Le istruzioni di I/O vengono strutturate seguendo una particolare astrazione detta “stream” (flusso) che rappresenta un "qualcosa" da o verso cui "fluisce" una sequenza di bytes.

Un oggetto stream può essere visto come un’“entità" da cui estrarre (input), o inserire (output) dei dati.

Page 36: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

36A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Overload degli operatori di flussoEsercizi sulle classi (1°parte)

… overload degli operatori di flusso << e >> …Gli operatori di scorrimento << e >> sono operatori binari. Producono lo scorrimento a destra / sinistra dei bit del primo operando (left‐operand) in quantità pari al valore indicato nel  right‐operand.

Shift a sinistra

Dentro la libreria iostream sono definite due classi globali, ostream e istream, corrispondenti agli stream di input e output. Queste due classi sovraccaricano gli operatori di scorrimento << e >>, dandogli la funzione di stampare e leggere dati.

In questa libreria vengono create due istanze delle classi ostream e istream: cout (Console Output) e cin (Console Input)  che vengono usate per stampare su schermo e leggere da tastiera. 

Nello stream l'operazione di output viene identificata mediante un'operazione di inserimento del dato (right operand) da scrivere nell'oggetto cout (left operand): 

cout << dato;

mentre l'operazione di input mediante un'operazione di estrazione del dato da leggere (rightoperand) dall'oggetto cin.

cin >> dato;

Page 37: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

37A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Overload degli operatori di flussoEsercizi sulle classi (1°parte)

Vediamo ora come estendere gli operatori di flusso anche ai tipi astratti in modo che l‘istruzione:

Prima di procedere dobbiamo fare due precisazioni:1) Abbiamo posto come right‐operand dell’operatore di flusso l’istanza Dato della nostra classe A.L’operando a sinistra dell’operatore di flusso è invece un’istanza istream o ostream (cin e cout), diversa dalla classe a cui appartiene Dato, quindi sarà necessario lavorare su funzioni friend.

cout << dato;

… overload degli operatori di flusso << e >> …

2) Nell’implementazione della funzione‐operatore dobbiamo individuare anche il tipo di valore che essa dovrà restituire.

In C++ una chiamata del tipo:

è lecita per il fatto che il valore restituito dall’overloading dell’operatore di scorrimento << è nuovamente l’oggetto cout. 

cout << 5 << endl << “ciao”;

generi a  video la stampa dei valori assunti dai membri di Dato (dove Dato è un'istanza di una classe A).

Page 38: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

38A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Overload degli operatori di flussoEsercizi sulle classi (1°parte)

… overload degli operatori di flusso << e >> 

un’ulteriore esecuzione semplifica progressivamente l’istruzione

cout << 5 << endl << “ciao”;

l’esecuzione di cout << 5 restituisce lo stesso cout per cui ottengo:

cout << endl << “ciao”;

cout << “ciao”;cout << endl << “ciao”;

In questo modo l’operazione si semplifica progressivamente:

Quindi il valore restituito dalla funzione di overload sarà il riferimento allo stream passato come argomento alla stessa. Inoltre il parametro della funzione‐operatore relativo allo stream deve essere passato come referencevisto che si deve lavorare sempre su quella particolare istanza.

I prototipi delle nostre due funzioni saranno quindi:

friend ostream& operator<< (ostream&, Dato);

Possiamo adesso passare all’implementazione dell’esercizio 2 sfruttando l’overloading degli operatori.

friend istream& operator>> (istream&, Dato&);

Page 39: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

39A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 – Soluzione alternativaEsercizi sulle classi (1°parte)

Complesso Complesso::somma(Complesso addendo) {

return Complesso (reale + addendo.reale, immag + addendo.immag); }

Complesso Complesso::operator+(Complesso addendo) {

return Complesso (reale + addendo.reale, immag + addendo.immag); }

Partendo dall’implementazione della somma mediante la funzione‐membro “convenzionale” …

… implemento l’overloading dell’operatore somma (+)

SOLUZIONE ALTERNATIVA

Utilizzando l’implementazione della funzione stampa() …

void Complesso::stampa() {if ( (reale!=0) || (immag==0) )

cout << reale;if (immag!=0) {

if ((immag > 0) && (reale!=0)) cout << "+";if (immag!=1) cout << immag;cout << "i";

}}

… scrivo l’overloading dell’operatore di flusso <<ostream& operator<<(ostream &output , Complesso numero) {

if ( (numero.reale!=0) || (numero.immag==0) )output << numero.reale;

if (numero.immag!=0){

if ((numero.immag > 0) && (numero.reale!=0)) output << "+";if (numero.immag!=1) output << numero.immag;output << "i";

}return output;

}

Page 40: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

40A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 – soluzione alternativaEsercizi sulle classi (1°parte)

int main() {Complesso n1, n2(3.5, 4);n1.stampa();n1 = n1.somma(n2);cout << " + ";n2.stampa();cout << " = ";n1.stampa();cout << endl;system("pause");return 0;

}

Partendo dal main() originale …

… riscrivo il nuovo main()

SOLUZIONE ALTERNATIVA

Al termine la nuova definizione della classe Complesso diventa:

istream& operator>>(istream& input , Complesso& numero){

cout << "Parte reale: ";input >> numero.reale;cout << "Parte immaginaria: "; input >> numero.immag;return input;

}

Complesso::Complesso() {cout << "Parte reale: ";cin >> reale;cout << "Parte immaginaria: "; cin >> immag;

}

Riprendendo l’implementazione del costruttore di default …

… effettuo l’overloading dell’operatore di flusso >>

int main() {Complesso n1, n2(3.5, 4);cin >> n1;cout << n1; n1 = n1 + n2;cout << " + " << n2 << " = " << n1 << endl;system("pause");return 0;

}

class Complesso {public:

. . .Complesso();Complesso somma(Complesso addendo);void stampa();. . .

};

class Complesso {public:

. . .Complesso operator+(Complesso addendo);friend ostream& operator<<(ostream &output, Complesso numero); friend istream& operator>>(istream& input, Complesso& numero);. . .

};

Page 41: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

41A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 – soluzione alternativaEsercizi sull’uso delle classi (1°parte)Soluzione completa …

/*************************************************************************** Nome: lab1-complesso-bis.c ** Autore: Alessandro Saetti ** Data: 6/4/10 ***************************************************************************/

#include <iostream>#include <stdlib.h>using namespace std;

class Complesso {public:Complesso();Complesso(float r, float i);Complesso operator+(Complesso addendo);friend ostream& operator<<(ostream &output , Complesso numero);

// Agisce come funzione globale (le passo esplicitamente l'oggetto su // cui operare) ma puo' accedere ai membri privati dell'oggettofriend istream& operator>>(istream& input , Complesso& numero);

private:float reale, immag;

};

Page 42: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

42A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 – soluzione alternativaEsercizi sull’uso delle classi (1°parte)… soluzione completa …

/* Nome: Complesso::Complesso* Scopo: Costruttore di default della classe complesso* Input: -* Output: -*/

Complesso::Complesso() {reale = 0;immag = 0;

} /* Nome: Complesso::Complesso* Scopo: Costruttore alternativo della classe complesso* Input: float r: la parte reale del numero complesso* float i: la parte immaginaria del numero complesso* Output: -*/

Complesso::Complesso(float r, float i) {reale = r;immag = i;

} /* Nome: Complesso::operator+* Scopo: Somma un numero complesso al numero complesso rappresentato * dall'oggetto* Input: Complesso addendo: il numero complesso da sommare

Page 43: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

43A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 – soluzione alternativaEsercizi sull’uso delle classi (1°parte)… soluzione completa …

* Output: Restituisce la somma tra i due numeri complessi* Nota: operator e' una parola chiave per il sovraccaricamento degli operatori*/

Complesso Complesso::operator+(Complesso addendo) {return Complesso(reale + addendo.reale, immag + addendo.immag);

}/* Nome: Complesso::operator<<* Scopo: Stampa il numero complesso * Input: ostream &output: Un flusso di dati* Complesso numero: Il numero complesso da stampare* Output: Il flusso di dati da stampare*/

ostream& operator<<(ostream &output , Complesso numero) {if ( (numero.reale!=0) || (numero.immag==0) )

output << numero.reale;if (numero.immag!=0) {

if ((numero.immag > 0) && (numero.reale!=0)) output << "+";if (numero.immag!=1) output << numero.immag;

output << "i";}

return output;}

Page 44: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

44A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 – soluzione alternativaEsercizi sull’uso delle classi (1°parte)… soluzione completa …

/* Nome: Complesso::operator>>* Scopo: Acquisisce un numero complesso * Input: ostream &output: Un flusso di dati* Complesso numero: Il numero complesso da inizializzare con i dati * acquisiti* Output: Il flusso di dati in cui salvare i dati*/

istream& operator>>(istream& input , Complesso& numero){

cout << "Parte reale: ";input >> numero.reale;cout << "Parte immaginaria: "; input >> numero.immag;return input;

}

/* Nome: main* Scopo: Gestione dei numeri complessi* Input: -* Output: 0 se il programma termina correttamente*/

Page 45: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

45A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 2 – soluzione alternativaEsercizi sull’uso delle classi (1°parte)… soluzione completa.

int main() {

Complesso n1, n2(3.5, 4);cin >> n1;

cout << n1; n1 = n1 + n2;

cout << " + " << n2 << " = " << n1 << endl;system("pause");return 0;

}

Page 46: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

46A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizi sulle classi (2º parte)3. Definire la classe studente (matricola, nome, cognome) con

– Un metodo che inizializza i dati dello studente (matricola, nome e cognome) con dati acquisiti da tastiera;

– Un metodo che visualizzi i dati dello studente.Sfruttando la classe precedente, definire la classe aula (gruppo di studenti) con

– Un costruttore che azzera in numero di studenti nel gruppo;– Un metodo che visualizza i dati degli studenti nel gruppo;– Un metodo che rimuove dal gruppo lo studente avente un numero di

matricola pari ad un intero acquisito da tastiera;– Un metodo che inserisce un nuovo studente nel gruppo.Scrivere un programma C++ che, sfruttando le classi precedentemente definite, supporti (tramite un menù di opzioni) l’aggiunta, la rimozione e la visualizzazione dei dati di studenti da un’aula.

Page 47: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

47A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizi sulle classi (2º parte)Definire la classe studente (matricola, nome, cognome) con

– Un metodo che inizializza i dati dello studente (matricola, nome e cognome) con dati acquisiti da tastiera;

– Un metodo che visualizzi i dati dello studente.Sfruttando la classe precedente, definire la classe aula (gruppo di studenti) con

– Un costruttore che azzera in numero di studenti nel gruppo;

– Un metodo che visualizza i dati degli studenti nel gruppo;

– Un metodo che rimuove dal gruppo lo studente avente un numero di matricola pari ad un intero acquisito da tastiera;

– Un metodo che inserisce un nuovo studente nel gruppo.Scrivere un programma C++ che, sfruttando le classi precedentemente definite, supporti (tramite un menù di opzioni) l’aggiunta, la rimozione e la visualizzazione dei dati di studenti da un’aula.

Page 48: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

48A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3Esercizi sulle classi (2°parte)

/*************************************************************************** Nome: casa3-studente.c ** Autore: Alessandro Saetti ** Data: 6/4/10 ***************************************************************************/

#include <iostream>

/** Nome: main* Scopo: Gestione di un gruppo di studenti* Input: -* Output: 0 se il programma termina correttamente*/

int main() {

return 0;}

Impostiamo la solita struttura iniziale  di un programma C, aggiungendo eventuali commenti

// Definizione classe

// Menu per gestire le chiamate ai metodi// fornite dalla classe AULA

Definire la classe studente (matricola, nome, cognome) con– Un metodo che inizializza i dati dello studente (matricola, nome e cognome) con dati acquisiti da tastiera;– Un metodo che visualizzi i dati dello studente.

Sfruttando la classe precedente, definire la classe aula (gruppo di studenti) con– Un costruttore che azzera in numero di studenti nel gruppo;– Un metodo che visualizza i dati degli studenti nel gruppo;– Un metodo che rimuove dal gruppo lo studente avente un numero di matricola pari ad un intero acquisito da tastiera;– Un metodo che inserisce un nuovo studente nel gruppo.

Scrivere un programma C++ che, sfruttando le classi precedentemente definite, supporti (tramite un menù di opzioni) l’aggiunta, la rimozione e la visualizzazione dei dati di studenti da un’aula.

Non aggiungiamo #include <stdlib.h> poiché non ci serve usare system(“Pause”) per sospendere l’esecuzione del nostro programma.Infatti  implementeremo un menù di opzioni che resta in attesa della scelta dell’utente.

Page 49: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

49A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3Esercizi sulle classi (2°parte)Definire la classe studente (matricola, nome, cognome) con

– Un metodo che inizializza i dati dello studente (matricola, nome e cognome) con dati acquisiti da tastiera;– Un metodo che visualizzi i dati dello studente.

Sfruttando la classe precedente, definire la classe aula (gruppo di studenti) con– Un costruttore che azzera in numero di studenti nel gruppo;– Un metodo che visualizza i dati degli studenti nel gruppo;– Un metodo che rimuove dal gruppo lo studente avente un numero di matricola pari ad un intero acquisito da tastiera;– Un metodo che inserisce un nuovo studente nel gruppo.

Scrivere un programma C++ che, sfruttando le classi precedentemente definite, supporti (tramite un menù di opzioni) l’aggiunta, la rimozione e la visualizzazione dei dati di studenti da un’aula.

‐ il metodo stampa() che visualizza i dati dello studente, …

/* Nome: Studente::stampa* Scopo: Stampa i dato dello studente* Input: -* Output: -*/

void Studente::stampa() {cout << matricola << " " << nome << " " << cognome << " " << endl;

}

/* Nome: Studente::Studente* Scopo: Costruttore di default della classe Studente* Input: -* Output: -*/

Studente::Studente() {strcpy(nome, "");strcpy(cognome, "");matricola = 0;

}

Implementiamo:‐ il costruttore di default(quello senza argomenti) per la classe studente, …

Page 50: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

50A.A. 2012/2013

Per la gestione dell’I/O utilizziamo gli oggetti globali di I/O cin e cout abbinati agli operatori di flusso << e >>.

Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3Esercizi sulle classi (2°parte)

/* Nome: Studente::inserisci* Scopo: Inizializza i dati dello studente * con valori acquisiti da tastiera* Input: -* Output: -*/

void Studente::inserisci() {cout << "Inserisci matricola: ";cin >> matricola; cout << "Inserisci nome: ";cin >> nome;cout << "Inserisci cognome: ";cin >> cognome;

}

Definire la classe studente (matricola, nome, cognome) con– Un metodo che inizializza i dati dello studente (matricola, nome e cognome) con dati acquisiti da tastiera;– Un metodo che visualizzi i dati dello studente.

Sfruttando la classe precedente, definire la classe aula (gruppo di studenti) con– Un costruttore che azzera in numero di studenti nel gruppo;– Un metodo che visualizza i dati degli studenti nel gruppo;– Un metodo che rimuove dal gruppo lo studente avente un numero di matricola pari ad un intero acquisito da tastiera;– Un metodo che inserisce un nuovo studente nel gruppo.

Scrivere un programma C++ che, sfruttando le classi precedentemente definite, supporti (tramite un menù di opzioni) l’aggiunta, la rimozione e la visualizzazione dei dati di studenti da un’aula.

‐ il metodo per inserire un nuovo studente …/* Nome: Studente::restituisciMatricola* Scopo: Restituisce la matricola dello studente* Input: -* Output: la matricola dello studente*/

int Studente::restituisciMatricola() {return matricola;

}

La funzione membro restituisceMatricola() restituisce il contenuto della variabile membro privata contenente la matricola. Questo metodo viene utilizzato dalla funzione membro elimina() della classe Aula che definiremo successivamente

class Studente {public:

Studente();void inserisci();void stampa();int restituisciMatricola();

private:char nome[DIM1];char cognome[DIM1];int matricola;

};

Possiamo quindi definire la classe studente

Page 51: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

51A.A. 2012/2013

/* Nome: Aula::Aula* Scopo: Costruttore di default * della classe Aula* Input: -* Output: -*/ Aula::Aula() {

n = 0; }

/* Nome: Aula::stampa* Scopo: Stampa i dati del* gruppo degli studenti* Input: -* Output: -*/ void Aula::stampa() {

int i;for (i = 0; i < n; i++)

aula[i].stampa();}

Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3Esercizi sulle classi (2°parte)Definire la classe studente (matricola, nome, cognome) con

– Un metodo che inizializza i dati dello studente (matricola, nome e cognome) con dati acquisiti da tastiera;– Un metodo che visualizzi i dati dello studente.

Sfruttando la classe precedente, definire la classe aula (gruppo di studenti) con– Un costruttore che azzera in numero di studenti nel gruppo;– Un metodo che visualizza i dati degli studenti nel gruppo;– Un metodo che rimuove dal gruppo lo studente avente un numero di matricola pari ad un intero acquisito da tastiera;– Un metodo che inserisce un nuovo studente nel gruppo.

Scrivere un programma C++ che, sfruttando le classi precedentemente definite, supporti (tramite un menù di opzioni) l’aggiunta, la rimozione e la visualizzazione dei dati di studenti da un’aula.

Implementiamo quindi la classe Aula ‐ il costruttore di default …

Implementiamo: ‐ il metodo che stampa gli studenti presenti in una istanza di tipo aula …

/* Nome: Aula::aggiungi* Scopo: Aggiungi uno studente al* gruppo degli studenti* Input: -* Output: -*/ void Aula::aggiungi() {

aula[n++].inserisci();}

‐ il metodo che consente di aggiungere un nuovo studente alla classe (in fondo) …

class Aula {public:

Aula();void aggiungi();void elimina();void stampa();

private:Studente aula[DIM2];int n;

};/* Nome: Aula::elimina* Scopo: Elimina uno studente dal gruppo* degli studenti* Input: -* Output: -*/ void Aula::elimina() {

int i, m;cout << "Inserisci matricola: ";cin >> m;for (i = 0; i < n; i++) {

if (aula[i].restituisciMatricola() == m) {aula[i] = aula[n-1];n = n - 1;

}}

}

‐ la funzione membro che chiede la matricola dello studente da eliminare. L’eliminazione avviene 

sostituendo lo studente da eliminare con l’ultimo in 

elenco

Page 52: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

52A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3Esercizi sulle classi (2°parte)Definire la classe studente (matricola, nome, cognome) con

– Un metodo che inizializza i dati dello studente (matricola, nome e cognome) con dati acquisiti da tastiera;– Un metodo che visualizzi i dati dello studente.

Sfruttando la classe precedente, definire la classe aula (gruppo di studenti) con– Un costruttore che azzera in numero di studenti nel gruppo;– Un metodo che visualizza i dati degli studenti nel gruppo;– Un metodo che rimuove dal gruppo lo studente avente un numero di matricola pari ad un intero acquisito da tastiera;– Un metodo che inserisce un nuovo studente nel gruppo.

Scrivere un programma C++ che, sfruttando le classi precedentemente definite, supporti (tramite un menù di opzioni) l’aggiunta, la rimozione e la visualizzazione dei dati di studenti da un’aula.

Impostiamo ilmain() con un menù opzioni che richiama le funzionalità rese disponibili dai metodi della classe Aula.

int main() {Aula eip;int x;do {

cout << "1. Stampa\n2. Inserisci\n3. Elimina\n0. Esci\n-> "; cin >> x;switch(x) {

case 1: eip.stampa();break;

case 2: eip.aggiungi();break;

case 3: eip.elimina();break;

}} while(x != 0);return 0;

}

Page 53: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

53A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3Esercizi sull’uso delle classi (2°parte)Soluzione completa…

/*************************************************************************** Nome: casa3-studente.c ** Autore: Alessandro Saetti ** Data: 6/4/10 ***************************************************************************/

#include <iostream>#include <string.h>#define DIM1 50#define DIM2 100#define TRUE 1#define FALSE 0

using namespace std;

class Studente {public:

Studente();void inserisci();void stampa();int restituisciMatricola();

private:char nome[DIM1];char cognome[DIM1];int matricola;

};

Page 54: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

54A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3Esercizi sull’uso delle classi (2°parte)…Soluzione completa…

class Aula {public:

Aula();void elimina();void stampa();

private:Studente aula[DIM2];int n;

};/* Nome: Studente::Studente* Scopo: Costruttore di default della classe Studente* Input: -* Output: -*/

Studente::Studente() {strcpy(nome, "");strcpy(cognome, "");matricola = 0;

}/* Nome: Studente::inserisci* Scopo: Inizializza i dati dello studente con valori acquisiti da tastiera* Input: -* Output: -*/

Page 55: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

55A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3Esercizi sull’uso delle classi (2°parte)

…Soluzione completa…

void Studente::inserisci() {

cout << "Inserisci matricola: ";cin >> matricola; cout << "Inserisci nome: ";cin >> nome;cout << "Inserisci cognome: ";cin >> cognome;

}/* Nome: Studente::stampa* Scopo: Stampa i dato dello studente* Input: -* Output: -*/

void Studente::stampa() {

cout << matricola << " " << nome << " " << cognome << " " << endl; }/* Nome: Studente::restituisciMatricola* Scopo: Restituisce la matricola dello studente* Input: -* Output: la matricola dello studente*/

int Studente::restituisciMatricola() {

return matricola;}

Page 56: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

56A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3Esercizi sull’uso delle classi (2°parte)…Soluzione completa…

/* Nome: Aula::Aula* Scopo: Costruttore di default della classe Aula* Input: -* Output: -*/

Aula::Aula() {n = 0;

}/* Nome: Aula::stampa* Scopo: Stampa i dati del gruppo degli studenti* Input: -* Output: -*/

void Aula::stampa() {int i;for(i = 0; i < n; i++) aula[i].stampa();

}/* Nome: Aula::aggiungi* Scopo: Aggiungi uno studente al gruppo degli studenti* Input: -* Output: -*/

void Aula::aggiungi(){

aula[n++].inserisci();}

Page 57: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

57A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3Esercizi sull’uso delle classi (2°parte)…Soluzione completa… /* Nome: Aula::elimina

* Scopo: Elimina uno studente dal gruppo degli studenti* Input: -* Output: -*/

void Aula::elimina() {int i, m;

cout << "Inserisci matricola: ";cin >> m;

for (i = 0; i < n; i++) {if (aula[i].restituisciMatricola() == m) {

aula[i] = aula[n-1];n = n - 1;

}}

}/* Nome: main* Scopo: Gestione di un gruppo di studenti* Input: -* Output: 0 se il programma termina correttamente*/

int main(){

Aula eip;int x;

Page 58: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

58A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizio 3Esercizi sull’uso delle classi (2°parte)…Soluzione completa…

do {cout << "1. Stampa\n2. Inserisci\n3. Elimina\n0. Esci\n-> "; cin >> x;switch(x) {

case 1: eip.stampa();break;

case 2: eip.aggiungi();break;

case 3: eip.elimina();break;

}} while(x != 0);return 0;

}

Page 59: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

59A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizi sulle classi (per casa)1. Definire la classe dei numeri razionali con

• Un costruttore che inizializza il denominatore con un intero casuale compreso tra 1 e 10 ed il numeratore con un numero casuale compreso tra 1 ed il denominatore;

• Un costruttore che inizializzi il numero razionale della classe con due dati interi.

• Un metodo che produca il numero reale pari al numero razionale della classe;

• Un metodo che inizializzi il numero razionale della classe con interi acquisiti da tastiera, riducendo il numero razionale ai minimi termini;

• Un metodo che produca il numero razionale (ridotto ai minimi termini) ottenuto sommando il numero razionale della classe con un secondo numero razionale;

Scrivere un programma C++ che, sfruttando la classe precedentemente definita, inizializzi e visualizzi un vettore di 10 numeri razionali ed infine visualizzi la somma dei 10 numeri razionali.

Page 60: Fondamenti di Programmazione - marco sechiDocente: A. Saetti Fondamenti di Programmazione -Università degli Studi di Brescia A.A. 2012/2013 2 Esercizi sulle classi (1ºparte) 1. Definire

60A.A. 2012/2013Docente: A. Saetti Fondamenti di Programmazione - Università degli Studi di Brescia

Esercizi sulle classi (per casa)2. Modificare la soluzione dell’esercizio precedente

affinché il programma sia in grado di gestire sia studenti della laurea triennale (matricola, nome e cognome) che studenti della laurea specialistica (matricola, nome, cognome e voto di laurea) utilizzando le seguenti indicazioni:

• Definire una gerarchia di classi (triennale e specialistica sono classi derivate della classe studente);

• Sfruttare il polimorfismo per virtualizzare i metodi della classe studente per l’acquisizione e la visualizzazione dei dati degli studenti della laurea triennale e degli studenti della laurea specialistica.