Esercitazioni LPS: differenze tra le versioni

Da Bioingegneria Elettronica e Informatica.
Riga 301: Riga 301:
  
  
== Funzioni virtuali pure e Classi Astratte 2==
+
== Esempi di costruttore di copie==
 
<syntaxhighlight lang="cpp" line>
 
<syntaxhighlight lang="cpp" line>
 
#include <iostream>
 
#include <iostream>
#include <cmath>
+
#include <new>
 
+
#include <cstdlib>
 
using namespace std;
 
using namespace std;
  
class Figura
+
// ATTENZIONE: in ambiente Visual Studio avviare senza eseguire Debug (CTRL+F5)
{
+
// Classe Astratta: contiene almeno una funzione virtuale pura
+
protected:
+
double perimetro;
+
double area;
+
public:
+
Figura() { perimetro = 0; area = 0; }
+
  
virtual void calcolaPerimetro() = 0; // Funzione virtuale pura
+
// Terzo esempio per creare costruttori di copie
virtual void calcolaArea() = 0; // Necessario ridefinire i metodi virtuali puri nelle classi derivati, altrimenti errore in compilazione
+
// N.B. quando si esegue una copia i due oggetti sono identici bit a bit,
};
+
// quando però la inizializzazione comporta l'allocazione di memoria non deve
 +
// essere fatta una copia bit a bit
  
class Triangolo : public Figura
+
// Questo programma crea una classe per array "sicuri"
{
+
private:
+
// Dimensione dei tre lati
+
double l1, l2, l3;
+
public:
+
Triangolo(double L1, double L2, double L3) {
+
l1 = L1; l2 = L2; l3 = L3;
+
}
+
  
void calcolaPerimetro() {
 
perimetro = l1 + l2 + l3;
 
cout << "Il perimetro del Triangolo con lati " <<
 
l1 << " " << l2 << " e " << l3 << " vale: " << perimetro << endl;
 
}
 
 
// Calcolo area con formula di Erone
 
void calcolaArea() {
 
double p = (l1 + l2 + l3) / 2;
 
area = sqrt(p*(p - l1)*(p - l2)*(p - l3));
 
cout << "L'area del Triangolo con lati " <<
 
l1 << " " << l2 << " e " << l3 << " vale: " << area << endl;
 
}
 
};
 
  
class Rettangolo : public Figura
+
class vettore
 
{
 
{
private:
+
int *p;
// Dimensione di base e altezza
+
int dimensione;
double l1, l2;
+
 
public:
 
public:
Rettangolo(double L1, double L2) {
+
vettore(int dim)
l1 = L1; l2 = L2;
+
{
}
+
cout << "costruzione" << endl;
void calcolaPerimetro() {
+
p = new int[dim];
perimetro = 2*(l1 + l2);
+
dimensione = dim;
cout << "Il perimetro del Rettangolo con lati " << l1 << " e " << l2 << " vale: " << perimetro << endl;
+
 
}
 
}
  
void calcolaArea() {
+
~vettore() { delete[] p; cout << "distruzione" << endl; }
area = l1 * l2;
+
// costruttore di copie
cout << "L'area del Rettangolo con lati " << l1 << " e " << l2 << " vale: " << area << endl;
+
vettore(const vettore &vett);
}
+
};
+
  
class Cerchio : public Figura
+
void imposta(int i, int j)
{
+
{
private:
+
if (i >= 0 && i <dimensione)
// Dimensione del raggio
+
p[i] = j;
double l1;
+
public:
+
Cerchio(double L1) {
+
l1 = L1;
+
}
+
void calcolaPerimetro() {
+
perimetro = 3.14 * 2 * l1;
+
cout << "La circonferenza del cerchio con raggio " << l1 << " vale: " << perimetro << endl;
+
 
}
 
}
  
void calcolaArea() {
+
int prendi(int i)
area = 3.14 * l1 * l1;
+
{
cout << "L'area del cerchio con raggio " << l1 << " vale: " << area << endl;
+
return p[i];
 
}
 
}
 
};
 
};
  
 +
// Costruttore di copie
  
int main()
+
vettore::vettore(const vettore &vett)
 
{
 
{
Figura f; // Errore: non è consentito istanziare oggetti di tipo classe astratta
+
int i;
Figura *f1;
+
p = new int[vett.dimensione];
Triangolo t1(10.3, 9, 18.3);
+
cout << "costruttore di copie" << endl;
Rettangolo r1(10, 3.5);
+
for (i = 0; i<vett.dimensione; i++)
Cerchio c1(10);
+
p[i] = vett.p[i];
 +
}
  
  
f1 = &t1;
+
int main()
f1->calcolaPerimetro();
+
{
f1->calcolaArea();
+
vettore num(10);
 +
int i;
 +
for (i = 0; i<10; i++) num.imposta(i, i);
 +
for (i = 9; i >= 0; i--) cout << num.prendi(i);
 +
cout << "\n";
  
f1 = &r1;
+
// i vettori num e x contengono gli stessi valori ma ciascun vettore
f1->calcolaPerimetro();
+
// si trova in aree diverse di memoria
f1->calcolaArea();
+
  
f1 = &c1;
+
// crea un altro vettore e lo inizializza con num
f1->calcolaPerimetro();
+
vettore x(num); // richiama il costruttore di copie;
f1->calcolaArea();
+
for (i = 0; i<10; i++) cout << num.prendi(i);
 
+
cout << "\nciao\n";
system("pause");
+
 
return 0;
 
return 0;
 
}
 
}
 +
 +
/*
 +
costruzione
 +
9876543210
 +
costruttore di copie
 +
0123456789
 +
ciao
 +
distruzione
 +
distruzione
 +
Press any key to continue
 +
*/
 
</syntaxhighlight>
 
</syntaxhighlight>

Versione delle 13:42, 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. }


Esempi di costruttore di copie

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