Esercitazioni LPS: differenze tra le versioni

Da Bioingegneria Elettronica e Informatica.
Riga 545: Riga 545:
 
using namespace std;
 
using namespace std;
  
// Esempio di lettura/scrittura di interi da/su file binario
+
// Esempio di lettura/scrittura di un vettore di interi da/su file binario
  
 
class vettore
 
class vettore

Versione delle 17:13, 29 mag 2019


Esercitazione del 2 e 15 maggio 2019

  1. // questo è un commento a linea singola in puro stile C++
  2.  
  3.  
  4. // la programmazione ad oggetti supporta //
  5. // l'incapsulamento
  6. // il polimorfismo
  7. // l'ereditarietà 
  8.  
  9. // esempio di incapsulamento: dati e funzioni in un oggetto
  10. // esempio di polimorfismo a compile time: overloading di funzioni
  11. // esempio di ereditarietà: classe persona e classe studente
  12. // esempio di costruttore per inizializzare variabili a valori di default
  13.  
  14.  
  15. // un oggetto è una istanza di una classe
  16.  
  17. // include la necessaria intestazione <iostream>
  18. #include <iostream>
  19.  
  20. // l'istruzione using informa il compilatore che intende utilizzare il namespace standard
  21. using namespace std;
  22. // i namespace creano delle regioni di dichiarazione
  23. // nel namespace standard viene dichiarata l'intera libreria standard del C++
  24.  
  25. // Creazione della classe persona
  26. // una classe può contenere attributi (variabili) e metodi (funzioni) privati, protetti e pubblici
  27. // per ora prevediamo soltanto attributi privati e metodi pubblici
  28. class persona {
  29. private: //private è pleonastico (si può omettere)
  30. 	int IDP;
  31. 	// IDP in quanto variabile privata non risulta visibile da funzioni che non siano metodi della classe persona
  32. public:
  33. 	void leggiIDP();
  34. 	void leggiIDP(int);
  35. 	void stampaIDP();
  36. // segue la funzione costruttore, omonima della classe, e nella cui dichiarazione non si specifica il valore restituito
  37. 	persona();
  38. // segue la funzione costruttore overloadata con un parametro
  39. 	persona(int);
  40. // segue la funzione distruttore, omonima della classe ma preceduta dal TILDE, e nella cui dichiarazione non si specifica il valore restituito
  41.         ~persona();
  42. };
  43.  
  44. class studente : public persona {
  45. private:
  46. 	int IDS;
  47. public:
  48. 	void leggiIDS();
  49. 	void stampaIPDS();
  50. 	studente();
  51.         ~studente();
  52. };
  53.  
  54. void persona::leggiIDP()
  55. {
  56.         cin >> IDP;
  57. }
  58. void persona::leggiIDP(int A)
  59. {
  60. 	IDP = A;
  61. }
  62. void persona::stampaIDP()
  63. {
  64. 	cout << IDP << endl;
  65. 	// endl per andare a capo
  66. }
  67.  
  68. persona::persona()
  69. {
  70.         cout << "Persona costruita " << endl;
  71. 	IDP = 0;
  72. }
  73.  
  74. persona::persona(int A)
  75. {
  76.         cout << "Persona costruita con parametro passato per valore " << endl;
  77. 	IDP = A;
  78. }
  79.  
  80. persona::~persona()
  81. {
  82.         cout << "Persona distrutta " << endl;
  83. }
  84.  
  85. studente::studente()
  86. {
  87.         cout << "Studente costruito " << endl;
  88. 	IDS = 0;
  89. }
  90.  
  91. studente::~studente()
  92. {
  93.         cout << "Studente distrutto " << endl;
  94. }
  95. void studente::leggiIDS()
  96. {
  97. 	cin >> IDS;
  98. }
  99.  
  100. void studente::stampaIPDS()
  101. {
  102. 	cout << "Identificativo studente pari a " << IDS << endl;
  103. }
  104.  
  105. // verificare il sorgente modificato ...
  106.  
  107. int main()
  108. {
  109. 	persona P, Q(3);
  110. 	studente S; // verifica della chiamata del costruttore di persona senza parametri
  111. 	// P.IDP=2; errore cannot access private member
  112. 	P.stampaIDP();
  113. 	P.leggiIDP();
  114. 	P.stampaIDP();
  115.         Q.stampaIDP();
  116. 	Q.leggiIDP(2);
  117. 	Q.stampaIDP();
  118.  
  119. 	S.leggiIDP();
  120. 	S.stampaIDP();
  121. 	S.leggiIDS();
  122. 	S.stampaIPDS();
  123.  
  124. 	// Decommentare su visual studio
  125. 	// system("pause");
  126. 	return 0;
  127. }

Funzioni virtuali

  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. class Base 
  6. {
  7. public:
  8. 	virtual void stampa() {
  9. 		cout << "Metodo stampa della classe Base" << endl;
  10. 	}
  11. };
  12.  
  13. class DerivataUno : public Base 
  14. {
  15. public:
  16. 	void stampa() {
  17. 		cout << "Metodo stampa della classe DerivataUno" << endl;
  18. 	}
  19. };
  20.  
  21. class DerivataDue : public Base
  22. {
  23. public:
  24. 	void funzione() {
  25. 		cout << "Funzione specifica della classe DerivataDue" << endl;
  26. 	}
  27. };
  28.  
  29. int main()
  30. {
  31. 	Base b, *p;
  32. 	DerivataUno d1;
  33. 	DerivataDue d2;
  34.  
  35. 	p = &b;
  36. 	// Richiamata la funzione stampa della classe Base
  37. 	p->stampa();
  38.  
  39. 	p = &d1;
  40. 	// Richiamata la funzione stampa della classe DerivataUno
  41. 	p->stampa();
  42.  
  43. 	p = &d2;
  44. 	// Richiamata la funzione stampa della classe Base
  45. 	p->stampa();
  46. 	// Richiama il metodo specifico della classe DerivataDue ->
  47. 	// -> cast a punatatore di tipo classe derivata
  48. 	((DerivataDue*)p)->funzione();
  49.  
  50. 	system("pause");
  51.  
  52. }

Funzioni virtuali pure e Classi Astratte

  1. #include <iostream>
  2. #include <cmath>
  3.  
  4. using namespace std;
  5.  
  6. class Figura
  7. {
  8. 	// Classe Astratta: contiene almeno una funzione virtuale pura
  9. protected:
  10. 	double perimetro;
  11. 	double area;
  12. public:
  13. 	Figura() { perimetro = 0; area = 0; }
  14.  
  15. 	virtual void calcolaPerimetro() = 0; // Funzione virtuale pura
  16. 	virtual void calcolaArea() = 0; // Necessario ridefinire i metodi virtuali puri nelle classi derivati, altrimenti errore in compilazione
  17. };
  18.  
  19. class Triangolo : public Figura
  20. {
  21. private:
  22. 	// Dimensione dei tre lati
  23. 	double l1, l2, l3;
  24. public:
  25. 	Triangolo(double L1, double L2, double L3) {
  26. 		l1 = L1; l2 = L2; l3 = L3;
  27. 	}
  28.  
  29. 	void calcolaPerimetro() {
  30. 		perimetro = l1 + l2 + l3;
  31. 		cout << "Il perimetro del Triangolo con lati " << 
  32. 			l1 << " " << l2 << " e " << l3 << " vale: " << perimetro << endl;
  33. 	}
  34.  
  35. 	// Calcolo area con formula di Erone
  36. 	void calcolaArea() { 
  37. 		double p = (l1 + l2 + l3) / 2;
  38. 		area = sqrt(p*(p - l1)*(p - l2)*(p - l3));
  39. 		cout << "L'area del Triangolo con lati " <<
  40. 			l1 << " " << l2 << " e " << l3 << " vale: " << area << endl;
  41. 	}
  42. };
  43.  
  44. class Rettangolo : public Figura
  45. {
  46. private:
  47. 	// Dimensione di base e altezza
  48. 	double l1, l2;
  49. public:
  50. 	Rettangolo(double L1, double L2) {
  51. 		l1 = L1; l2 = L2;
  52. 	}
  53. 	void calcolaPerimetro() {
  54. 		perimetro = 2*(l1 + l2);
  55. 		cout << "Il perimetro del Rettangolo con lati " << l1 << " e " << l2 << " vale: " << perimetro << endl;
  56. 	}
  57.  
  58. 	void calcolaArea() {
  59. 		area = l1 * l2;
  60. 		cout << "L'area del Rettangolo con lati " << l1 << " e " << l2 << " vale: " << area << endl;
  61. 	}
  62. };
  63.  
  64. class Cerchio : public Figura
  65. {
  66. private:
  67. 	// Dimensione del raggio
  68. 	double l1;
  69. public:
  70. 	Cerchio(double L1) {
  71. 		l1 = L1;
  72. 	}
  73. 	void calcolaPerimetro() {
  74. 		perimetro = 3.14 * 2 * l1;
  75. 		cout << "La circonferenza del cerchio con raggio " << l1 << " vale: " << perimetro << endl;
  76. 	}
  77.  
  78. 	void calcolaArea() {
  79. 		area = 3.14 * l1 * l1;
  80. 		cout << "L'area del cerchio con raggio " << l1 << " vale: " << area << endl;
  81. 	}
  82. };
  83.  
  84.  
  85. int main()
  86. {
  87. 	Figura f; // Errore: non è consentito istanziare oggetti di tipo classe astratta
  88. 	Figura *f1;
  89. 	Triangolo t1(10.3, 9, 18.3);
  90. 	Rettangolo r1(10, 3.5);
  91. 	Cerchio c1(10);
  92.  
  93.  
  94. 	f1 = &t1;
  95. 	f1->calcolaPerimetro();
  96. 	f1->calcolaArea();
  97.  
  98. 	f1 = &r1;
  99. 	f1->calcolaPerimetro();
  100. 	f1->calcolaArea();
  101.  
  102. 	f1 = &c1;
  103. 	f1->calcolaPerimetro();
  104. 	f1->calcolaArea();
  105.  
  106. 	system("pause");
  107. 	return 0;
  108. }


Costruttore di copia di un vettore

  1. #include <iostream>
  2. #include <new>
  3. #include <cstdlib>
  4. using namespace std;
  5.  
  6. // ATTENZIONE: in ambiente Visual Studio avviare senza eseguire Debug (CTRL+F5)
  7.  
  8. // N.B. quando si esegue una copia i due oggetti sono identici bit a bit,
  9. // quando però la inizializzazione comporta l'allocazione di memoria non deve
  10. // essere fatta una copia bit a bit 
  11.  
  12. // Questo programma crea una classe per array "sicuri"
  13.  
  14.  
  15. class vettore
  16. {
  17. 	int *p;
  18. 	int dimensione;
  19. public:
  20. 	vettore(int dim)
  21. 	{
  22. 		cout << "costruzione" << endl;
  23. 		p = new int[dim];
  24. 		dimensione = dim;
  25. 	}
  26.  
  27. 	~vettore() { delete[] p; cout << "distruzione" << endl; }
  28. 	// costruttore di copie
  29. 	vettore(const vettore &vett);
  30.  
  31. 	void imposta(int i, int j)
  32. 	{
  33. 		if (i >= 0 && i <dimensione)
  34. 			p[i] = j;
  35. 	}
  36.  
  37. 	int prendi(int i)
  38. 	{
  39. 		return p[i];
  40. 	}
  41. };
  42.  
  43. // Costruttore di copie
  44.  
  45. vettore::vettore(const vettore &vett)
  46. {
  47. 	int i;
  48. 	p = new int[vett.dimensione];
  49. 	cout << "costruttore di copie" << endl;
  50. 	for (i = 0; i<vett.dimensione; i++)
  51. 		p[i] = vett.p[i];
  52. }
  53.  
  54.  
  55. int main()
  56. {
  57. 	vettore num(10);
  58. 	int i;
  59. 	for (i = 0; i<10; i++) num.imposta(i, i);
  60. 	for (i = 9; i >= 0; i--) cout << num.prendi(i);
  61. 	cout << "\n";
  62.  
  63. 	// i vettori num e x contengono gli stessi valori ma ciascun vettore
  64. 	// si trova in aree diverse di memoria
  65.  
  66. 	// crea un altro vettore e lo inizializza con num
  67. 	vettore x(num); // richiama il costruttore di copie;
  68. 	for (i = 0; i<10; i++) cout << num.prendi(i);
  69. 	cout << "\nciao\n";
  70. 	return 0;
  71. }
  72.  
  73. /*
  74. costruzione
  75. 9876543210
  76. costruttore di copie
  77. 0123456789
  78. ciao
  79. distruzione
  80. distruzione
  81. Press any key to continue
  82. */

Costruttore di copia di una matrice

  1. #include <iostream>
  2. #include <new>
  3. #include <cstdlib>
  4. using namespace std;
  5.  
  6. // ATTENZIONE: in ambiente Visual Studio avviare senza eseguire Debug (CTRL+F5)
  7.  
  8. // N.B. quando si esegue una copia i due oggetti sono identici bit a bit,
  9. // quando però la inizializzazione comporta l'allocazione di memoria non deve
  10. // essere fatta una copia bit a bit 
  11.  
  12. // Questo programma crea una classe per array bidimensionali "sicuri"
  13.  
  14.  
  15. class matrice
  16. {
  17. 	int **p;
  18. 	int dimRighe;
  19. 	int dimColonne;
  20. public:
  21. 	matrice(int r, int c)
  22. 	{
  23. 		cout << "Costruzione matrice e inizializzazione degli elementi a zero" << endl;
  24. 		dimRighe = r;
  25. 		dimColonne = c;
  26.  
  27. 		p = new int *[r];
  28.  
  29. 		for (int i = 0; i < dimRighe; i++) {
  30. 			p[i] = new int[dimColonne];
  31. 		}
  32.  
  33. 		int i, j;
  34. 		for (i = 0; i < dimRighe; i++) {
  35. 			for (j = 0; j < dimColonne; j++) {
  36. 				p[i][j] = 0;
  37. 			}
  38. 		}
  39.  
  40.  
  41. 		cout << endl;
  42. 	}
  43.  
  44. 	~matrice() { 
  45. 		for (int i = 0; i < dimRighe; i++) {
  46. 			delete[] p[i];
  47. 		}
  48. 		delete[] p;
  49. 		cout << "Distruzione della matrice creata nel main alla fine del main" << endl;
  50. 	}
  51.  
  52. 	// costruttore di copie
  53. 	matrice(const matrice &mat);
  54.  
  55. 	void stampa() {
  56. 		cout << "Stampa elementi matrice: " << endl;
  57. 		int i, j;
  58. 		for (i = 0; i < dimRighe; i++) {
  59. 			cout << endl;
  60. 			for (j = 0; j < dimColonne; j++) {
  61. 				cout << p[i][j];
  62. 			}
  63. 		}
  64.  
  65. 		cout << endl << endl;
  66. 	}
  67.  
  68. 	void modificaMatrice() {
  69. 		cout << "Modifica elementi matrice ( +1 ): " << endl;
  70. 		int i, j;
  71. 		for (i = 0; i < dimRighe; i++) {
  72. 			for (j = 0; j < dimColonne; j++) {
  73. 				p[i][j] = p[i][j] + 1;
  74. 			}
  75. 		}
  76. 		cout << endl;
  77. 	}
  78.  
  79. };
  80.  
  81. // Costruttore di copie
  82. matrice::matrice(const matrice &mat)
  83. {
  84. 	cout << "Costruttore di copie della matrice" << endl;
  85. 	dimRighe = mat.dimRighe;
  86. 	dimColonne = mat.dimColonne;
  87.  
  88. 	p = new int *[dimRighe];
  89. 	for (int i = 0; i < dimRighe; i++) {
  90. 		p[i] = new int[dimColonne];
  91. 	}
  92.  
  93. 	int i, j;
  94. 	for (i = 0; i < dimRighe; i++) {
  95. 		for (j = 0; j < dimColonne; j++) {
  96. 			p[i][j] = mat.p[i][j];
  97. 		}
  98. 	}
  99.  
  100. 	cout << endl;
  101. }
  102.  
  103. int main()
  104. {
  105.  
  106. 	matrice m1(2,3);
  107. 	m1.stampa();
  108.  
  109. 	matrice m2(m1);
  110. 	m2.stampa();
  111.  
  112. 	m1.modificaMatrice();
  113. 	m1.stampa();
  114.  
  115. 	return 0;
  116. }
  117.  
  118. /*
  119. Costruzione matrice e inizializzazione degli elementi a zero
  120.  
  121. Stampa elementi matrice:
  122.  
  123. 000
  124. 000
  125.  
  126. Costruttore di copie della matrice
  127.  
  128. Stampa elementi matrice:
  129.  
  130. 000
  131. 000
  132.  
  133. Modifica elementi matrice ( +1 ):
  134.  
  135. Stampa elementi matrice:
  136.  
  137. 111
  138. 111
  139.  
  140. Distruzione della matrice creata nel main alla fine del main
  141. Distruzione della matrice creata nel main alla fine del main
  142. Premere un tasto per continuare . . .
  143.  
  144. */


Lettura e Scrittura di un file binario

  1. #include <iostream>
  2. #include <new>
  3. #include <cstdlib>
  4. #include <fstream>
  5.  
  6. using namespace std;
  7.  
  8. // Esempio di lettura/scrittura di un vettore di interi da/su file binario
  9.  
  10. class vettore
  11. {
  12.  
  13. public:
  14. 	int *p;
  15. 	int dimensione;
  16.  
  17. 	vettore(int dim)
  18. 	{
  19. 		//	costruzione di un vettore di dimensione dim
  20. 		dimensione = dim;
  21. 		p = new int[dimensione];
  22. 	}
  23.  
  24. 	vettore(const vettore &vett);
  25.  
  26. 	void generaRandom() {
  27. 		//	inizializzazione con elementi random nell'intervallo [1,100]
  28. 		for (int i = 0; i < dimensione; i++)
  29. 			p[i] = rand() % 100 + 1;
  30.  
  31. 	}
  32.  
  33. 	void inserisci() {
  34. 		//	inizializzazione con elementi inseriti manualmente
  35. 		for (int i = 0; i < dimensione; i++) {
  36. 			cout << "Inserisci elemento " << i << ":" << endl;
  37. 			cin >> p[i];
  38. 		}
  39. 	}
  40.  
  41. 	void imposta(int *arr) {
  42. 		//	inizializzazione con elementi di un array
  43. 		for (int i = 0; i < dimensione; i++)
  44. 			p[i] = arr[i];
  45.  
  46. 	}
  47.  
  48. 	void stampa() {
  49. 		//	stampa elementi del vettore
  50. 		for (int i = 0; i < dimensione; i++)
  51. 			cout << p[i] << " ";
  52.  
  53. 		cout << endl;
  54. 	}
  55.  
  56. 	void salvaSuFileBin() {
  57.  
  58. 		//apre il file binario in scrittura
  59. 		ofstream fileBinario("binario.dat", ios::binary);
  60.  
  61. 		//scrive l'array di elementi
  62. 		fileBinario.write((char*)p, sizeof(int)*dimensione);
  63.  
  64. 		// scrivo la dimensione del vettore
  65. 		fileBinario.write((char*)&dimensione, sizeof(int));
  66.  
  67. 		// chiudo il file
  68. 		fileBinario.close();
  69. 	}
  70.  
  71. 	~vettore() { 
  72. 		// distruzione vettore di interi allocato
  73. 		delete[] p;
  74. 	}
  75. };
  76.  
  77. vettore::vettore(const vettore &vett)
  78. {
  79. 	dimensione = vett.dimensione;
  80. 	int i;
  81. 	p = new int[vett.dimensione];
  82. 	cout << "Costruttore di copie" << endl;
  83. 	for (i = 0; i<vett.dimensione; i++)
  84. 		p[i] = vett.p[i];
  85. }
  86.  
  87. vettore leggiDaFileBin();
  88.  
  89.  
  90. int main()
  91. {
  92. 	int numInteri;
  93.  
  94. 	cout << "Quanti interi conterra' il file binario?" << endl;
  95. 	cin >> numInteri;
  96.  
  97. 	cout << "Generazione file binario con " << numInteri << " interi." << endl;
  98. 	vettore v1(numInteri);
  99. 	v1.generaRandom();
  100. 	//v1.inserisci();
  101. 	v1.stampa();
  102. 	v1.salvaSuFileBin();
  103.  
  104. 	vettore v2 = leggiDaFileBin();
  105. 	v2.stampa();
  106. 	return 0;
  107. }
  108.  
  109.  
  110.  
  111. vettore leggiDaFileBin() {
  112.  
  113. 	int numInteri;
  114.  
  115. 	//apre il file binario in lettura
  116. 	ifstream fileBinario("binario.dat", ios::binary); 
  117.  
  118. 	// posiziono il puntatore di lettura in modo da leggere l'ultimo intero scritto sul file
  119. 	fileBinario.seekg(-4, ios::end);
  120.  
  121. 	// leggo l'intero
  122. 	fileBinario.read((char*)&numInteri, sizeof(int));
  123.  
  124. 	// creo un array di interi per contenere tutti gli elementi sul file
  125. 	int *arr = new int[numInteri];
  126.  
  127. 	// riposiziono il puntatore di lettura all'inizio del file
  128. 	fileBinario.seekg(0);
  129.  
  130. 	// leggo l'array di interi intero
  131. 	fileBinario.read((char *)arr, sizeof(int)*numInteri);
  132.  
  133. 	// chiudo il file
  134. 	fileBinario.close();
  135.  
  136. 	vettore v(numInteri);
  137. 	v.imposta(arr);
  138.  
  139. 	return v;
  140. }