Lezione del 12/7/2006¶
-
Il template, motivazione ed esempi
File ex017.cc
1/* 2 * Cosa ha di diverso il C++ ad alto livello 3 * 4 */ 5 6/* 7 * i template, motivazioni 8 * 9 */ 10 11#include <iostream> 12 13/* 14 * Definisco 2 versioni del bubble sort, 15 * una per gli "int" e una per i "double" 16 */ 17 18// VERSIONE 1 19// algoritmo bubble sort per interi 20void 21sort( int const N, int V[] ) { 22 for ( int i = 0 ; i < N-1 ; ++i ) 23 for ( int j = i+1 ; j < N ; ++j ) 24 if ( V[i] > V[j] ) { 25 int bf = V[i] ; V[i] = V[j] ; V[j] = bf ; 26 } 27} 28 29// VERSIONE 2 30// algoritmo bubble sort per double 31void 32sort( int const N, /* cambio tipo */ double V[] ) { 33 for ( int i = 0 ; i < N-1 ; ++i ) 34 for ( int j = i+1 ; j < N ; ++j ) 35 if ( V[i] > V[j] ) { 36 /* cambio tipo */ double bf = V[i] ; V[i] = V[j] ; V[j] = bf ; 37 } 38} 39 40int 41main() { 42 int VI[] = {1,23,34,-2,4,3} ; 43 double VR[] = {1.3,23,34.3,-2.1,4,3} ; 44 45 int nVI = sizeof(VI)/sizeof(VI[0]) ; // totale elementi di VI 46 int nVR = sizeof(VR)/sizeof(VR[0]) ; // totale elementi di VR 47 48 // Sfruttando l'overloading viene richiata la routine giusta. 49 sort( nVI, VI ); // uso la VERSIONE 1 50 sort( nVR, VR ); // uso la VERSIONE 2 51 52 /* 53 * Anche se l'overloading permette di usare lo stesso nome 54 * per lo stesso algoritmo che opera su tipi diversi, 55 * devo comunque "riscrivere" l'algortitmo per ogni tipo 56 * che uso. 57 * Ad esempio se voglio l'algoritmo di ordinamento per i float 58 * o i long int devo riscrivere ancora una volta l'algoritmo. 59 */ 60}
File ex018.cc
1/* 2 * Cosa ha di diverso il C++ ad alto livello 3 * 4 */ 5 6/* 7 * i template, motivazioni 8 * 9 */ 10 11#include <iostream> 12 13/* 14 * SOluzioni alla C per la proliferazione dell'algortimo 15 */ 16 17// MODO C 18// algoritmo bubble sort per tipi generici, 19// devo passare la dimensione (in byte del tipo) 20// e una routine per il confronto 21void 22sort( int const N, // numero di elementi di ordinare 23 void * V, // puntatore all'inizio del vettore 24 int const size_V, // dimensione in byte del singolo elemento del vettore 25 bool (*GT)(void const * a, void const * b) 26 // routine di confronto 27 // se l'elemento all'indirizzo puntato da a 28 // e' maggiore dell'elemento puntato da b 29 // allora ritorna "true" altrimenti "false" 30 ) { 31 32 for ( int i = 0 ; i < N-1 ; ++i ) 33 for ( int j = i+1 ; j < N ; ++j ) { 34 char * Vi = (char*)V+i*size_V ; // vado al i esimo elemento del vettore V. 35 // V e' puntatatore a void e quindi per lui 36 // non vale l'aritmetica dei puntatori. 37 // faccio un "cast" ad un puntatore a carattere. 38 // In questo modo per andare all'elemento 39 // i-esimo basta spostarsi di i*size_V byte 40 // in avanti. 41 char * Vj = (char*)V+j*size_V ; 42 if ( GT(Vi,Vj) ) { // richiamo la rotine di confronto 43 // scambio size_V bytes 44 for ( int k = 0 ; k < size_V ; ++k ) { 45 char bf = Vi[k] ; 46 Vi[k] = Vj[k] ; 47 Vj[k] = bf ; 48 } 49 } 50 } 51} 52 53// rifinitura per int e double 54bool 55GT_int(void const * a, void const * b) { 56 int const * pA = (int const *)a ; 57 int const * pB = (int const *)b ; 58 return *pA > *pB ; 59} 60 61bool 62GT_double(void const * a, void const * b) { 63 double const * pA = (double const *)a ; 64 double const * pB = (double const *)b ; 65 return *pA > *pB ; 66} 67 68int 69main() { 70 int VI[] = {1,23,34,-2,4,3} ; 71 double VR[] = {1.3,23,34.3,-2.1,4,3} ; 72 73 int nVI = sizeof(VI)/sizeof(VI[0]) ; // totale elementi di VI 74 int nVR = sizeof(VR)/sizeof(VR[0]) ; // totale elementi di VR 75 76 sort( nVI, VI, sizeof(int), GT_int ); // uso la VERSIONE int 77 sort( nVR, VR, sizeof(double), GT_double ); // uso la VERSIONE double 78 79 // Problemi: 80 // -- Bisogna definire le routine di confronto per ogni tipo 81 // -- Bisogna passare 2 parametri extra, uno per la dimensione 82 // in byte del tipo, e uno per il puntatore alla funzione 83 // di confronto. 84 // -- Introdurre altri parametri aumenta la possibilita di errore 85 // (ad esempio passo la dimensione in byte sbagliata o la 86 // routine di confronto sbagliata) 87 // -- L'uso del puntatore a funzione introduce un "overhead" e quindi 88 // rende il programma meno efficiente. 89 90}
File ex019.cc
1/* 2 * Cosa ha di diverso il C++ ad alto livello 3 * 4 */ 5 6/* 7 * i template, motivazioni 8 * 9 */ 10 11/* 12 * Definisco una versioni del bubble sort, 13 * con una macro 14 */ 15 16#define BUBBLE_SORT(TIPO) \ 17void \ 18sort( int const N, TIPO V[] ) { \ 19 for ( int i = 0 ; i < N-1 ; ++i ) \ 20 for ( int j = i+1 ; j < N ; ++j ) \ 21 if ( V[i] > V[j] ) { \ 22 TIPO bf = V[i] ; V[i] = V[j] ; V[j] = bf ; \ 23 } \ 24} 25 26BUBBLE_SORT(int) // genero il codice bubble sort per il tipo int 27BUBBLE_SORT(float) 28BUBBLE_SORT(double) 29BUBBLE_SORT(long int) 30 31int 32main() { 33 int VI[] = {1,23,34,-2,4,3} ; 34 double VR[] = {1.3,23,34.3,-2.1,4,3} ; 35 36 int nVI = sizeof(VI)/sizeof(VI[0]) ; // totale elementi di VI 37 int nVR = sizeof(VR)/sizeof(VR[0]) ; // totale elementi di VR 38 39 // Sfruttando l'overloading viene richiata la routine giusta. 40 sort( nVI, VI ); // uso la VERSIONE 1 41 sort( nVR, VR ); // uso la VERSIONE 2 42 43 /* 44 * Questa soluzione permette di scrivere una volta sola l'algoritmo 45 * ma ha alcuni problemi: 46 * -- Bisogna ricordardi di scrivere BUBBLE_SORT(tipo) per ogni 47 * tipo che ci interessa 48 * -- E' piuttosco scomodo scrivere algoritmi lunghi con le macro 49 */ 50}
File ex020.cc
1/* 2 * Cosa ha di diverso il C++ ad alto livello 3 * 4 */ 5 6/* 7 * Soluzione con i template 8 * 9 */ 10 11#include <iostream> 12 13/* 14 * Soluzioni alla C++ per evitare la proliferazione dell'algortimo 15 */ 16 17// algoritmo bubble sort 18// versione generica 19template <typename TIPO_GENERICO> 20void 21sort( int const N, TIPO_GENERICO V[] ) { 22 for ( int i = 0 ; i < N-1 ; ++i ) 23 for ( int j = i+1 ; j < N ; ++j ) 24 if ( V[i] > V[j] ) { 25 TIPO_GENERICO bf = V[i] ; V[i] = V[j] ; V[j] = bf ; 26 } 27} 28// di fatto ho una routine di "tipo" 29// void sort( int const, T []) 30 31 32int 33main() { 34 int VI[] = {1,23,34,-2,4,3} ; 35 double VR[] = {1.3,23,34.3,-2.1,4,3} ; 36 37 int nVI = sizeof(VI)/sizeof(VI[0]) ; // totale elementi di VI 38 int nVR = sizeof(VR)/sizeof(VR[0]) ; // totale elementi di VR 39 40 sort( nVI, VI ); // cerco un matching con void sort( int const, int []) 41 // quindi il compilatore "espande" la defizione 42 // cons TIPO_GENERICO = int 43 sort( nVR, VR ); // cerco un matching con void sort( int const, double []) 44 // quindi il compilatore "espande" la defizione 45 // cons TIPO_GENERICO = double 46 47 // vantaggi se ora volessi ordinare un vettore di float 48 // basta scrivere 49 float VF[] = {1,23,34,-2,4,3} ; 50 int nVF = sizeof(VF)/sizeof(VF[0]) ; // totale elementi di VR 51 sort( nVF, VF ); 52}
File ex021.cc
1/* 2 * Cosa ha di diverso il C++ ad alto livello 3 * 4 */ 5 6#include <iostream> 7#include <cmath> 8 9/* 10 * Soluzioni alla C++ per evitare la proliferazione dell'algortimo 11 */ 12 13// algoritmo distanza tra 2 punti 14// versione generica 15template <typename T> 16inline 17T 18sqr( T const & a) 19{ return a*a ; } 20 21template <typename Tc, typename Ta, typename Tb> 22Tc 23dist( Ta const a[2], Tb const b[2] ) { 24 using std::sqrt ; 25 Tc res = sqrt( sqr(a[0]-b[0]) + sqr(a[1]-b[1]) ); 26 return res ; 27} 28 29int 30main() { 31 double a[] = {1.3,23} ; 32 float b[] = {34.3,-2.1,4,3} ; 33 34 // double res = dist( a, b ) ; 35 // scritto in questo modo il compilatore non e' in grado 36 // di fare in "matching" con la routine giusta. 37 // Infatti non controlla il tipo di ritorno. 38 double res1 = dist<double,double,float>( a, b ) ; 39 // istruisco il compilatore sul matching completo 40 double res2 = dist<double>( a, b ) ; 41 // istruisco il compilatore sul matching solo 42 // del primo argomento, gli altri due li deduce 43 double res3 = dist<double,double,double>( a, b ) ; 44 // non funziona perche dist( double const [2], double const [2]) 45 // non combacia con gli argomenti double,float!. 46}
-
Strutture con metodi
File ex022.cc
1/* 2 * Strutture con metodi 3 */ 4 5 6/* 7 * In C++ ad una struttura si possono 8 * aggiungere funzioni (chiamati metodi) che 9 * operano sulla stessa. 10 * Prima di usare i metodi vediamo come in C si 11 * struttura un programma per gestire ad esempio 12 * dei punti bidimensionali 13 * 14 */ 15 16#include <iostream> 17#include <cmath> 18 19using namespace std ; 20 21/* definisco la struttura punto2d */ 22typedef struct { 23 double x, y ; 24} point2d ; 25 26void 27init( point2d & pnt ) { 28 pnt.x = pnt.y = 0 ; 29} 30 31void 32set( point2d & pnt, double const x, double const y ) { 33 pnt.x = x ; 34 pnt.y = y ; 35} 36 37void 38move_x( point2d & pnt, double const tx ) { 39 pnt.x += tx ; 40} 41 42void 43move_y( point2d & pnt, double const ty ) { 44 pnt.y += ty ; 45} 46 47// + pnt nuova posizione 48// / + pnt 49// / / 50// / / 51// / 52// + center 53// 54// 55 56void 57rotate( point2d & pnt, // punto da muovere 58 double alpha, // angolo in radianti (senso antioario) 59 point2d & center // centro di rotazione 60 ) { 61 double dx = pnt . x - center . x ; 62 double dy = pnt . y - center . y ; 63 double dst = sqrt( dx*dx+dy*dy ) ; 64 double beta = atan2( dy, dx ); // dato il vettore (x,y) atan2(y,x) restituisce 65 // il suo angolo in radianti 66 pnt.x = center.x + dst * cos( alpha+beta ) ; 67 pnt.y = center.y + dst * sin( alpha+beta ) ; 68} 69 70void 71print( point2d const & pnt, ostream & s ) { 72 s << "[ " << pnt . x << " , " << pnt.y << "]" ; 73} 74 75int 76main() { 77 point2d a, b, c, d ; 78 79 set( a, 1, 2) ; 80 set( b, 2, .1) ; 81 set( c, -1, -3) ; 82 set( d, 0.3, 1) ; 83 84 move_x( a, 12) ; 85 move_y( b, -3) ; 86 87 rotate( a, 0.31, b ) ; 88 89 cout << "a = " ; print( a, cout ) ; cout << "\n" ; 90 cout << "b = " ; print( b, cout ) ; cout << "\n" ; 91 cout << "c = " ; print( c, cout ) ; cout << "\n" ; 92 cout << "d = " ; print( d, cout ) ; cout << "\n" ; 93 94 /* 95 * Anche se l'approccio e' valido si puo' fare di meglio in C++ 96 */ 97 98 return 0 ; 99}
File ex023.cc
1/* 2 * Strutture con metodi 3 */ 4 5 6/* 7 * In C++ ad una struttura si possono 8 * aggiungere funzioni (chiamati metodi) che 9 * operano sulla stessa. 10 */ 11 12#include <iostream> 13#include <cmath> 14 15using namespace std ; 16 17/* definisco la struttura punto2d */ 18typedef struct point2d { 19 double x, y ; 20 /* Invecie che definire delle funzioni esterne, definisco dei 21 metodiinterni alla struttura */ 22 23 void 24 init() { 25 x = y = 0 ; 26 } 27 28 void 29 set( double const x, double const y ) { 30 // this e' puntatore a se stesso cioe' la struttura stessa 31 // x o this -> x e' la stessa cosa a meno x non sia un argomento 32 // o variabile dichiarata nel metodo per cui diventa 33 // inaccessibile. 34 this -> x = x ; 35 this -> y = y ; 36 } 37 38 void 39 move_x( double const tx ) { 40 x += tx ; 41 } 42 43 void 44 move_y( double const ty ) { 45 y += ty ; 46 } 47 48 void 49 rotate( double alpha, // angolo in radianti (senso antioario) 50 struct point2d & center // centro di rotazione 51 ) { 52 double dx = x - center . x ; 53 double dy = y - center . y ; 54 double dst = sqrt( dx*dx+dy*dy ) ; 55 double beta = atan2( dy, dx ); // dato il vettore (x,y) atan2(y,x) restituisce 56 // il suo angolo in radianti 57 x = center.x + dst * cos( alpha+beta ) ; 58 y = center.y + dst * sin( alpha+beta ) ; 59 } 60 61 void 62 print( ostream & s ) { 63 s << "[ " << x << " , " << y << "]" ; 64 } 65 66} point2d ; 67 68int 69main() { 70 point2d a, b, c, d ; 71 72 a . set( 1, 2) ; 73 b . set( 2, .1) ; 74 c . set( -1, -3) ; 75 d . set( 0.3, 1) ; 76 77 a . move_x( 12) ; 78 b . move_y( -3) ; 79 80 a . rotate( 0.31, b ) ; 81 82 cout << "a = " ; a . print( cout ) ; cout << "\n" ; 83 cout << "b = " ; b . print( cout ) ; cout << "\n" ; 84 cout << "c = " ; c . print( cout ) ; cout << "\n" ; 85 cout << "d = " ; d . print( cout ) ; cout << "\n" ; 86 87 /* 88 * Anche se l'approccio e' valido si puo' fare di meglio in C++ 89 */ 90 91 return 0 ; 92}
-
Strutture con metodi ed uso degli operatori
File ex024.h
1/* 2 * Strutture con metodi 3 */ 4 5 6/* 7 * In C++ ad una struttura si possono 8 * aggiungere funzioni (chiamati metodi) che 9 * operano sulla stessa. 10 * 11 * Si possono anche definire gli operatori standard + - * / etc 12 * come operano sulla struttura 13 */ 14#ifndef EX024_H 15#define EX024_H 16 17#include <iostream> 18#include <cmath> 19 20using namespace std ; 21 22/* definisco la struttura punto2d */ 23typedef struct point2d { 24 double x, y ; 25 /* Invecie che definire delle funzioni esterne, definisco dei 26 metodi interni alla struttura */ 27 28 // definisco solo i prototipi 29 void init() ; 30 void set( double const x, double const y ) ; 31 void move_x( double const tx ) ; 32 void move_y( double const ty ) ; 33 void rotate( double alpha, struct point2d & center ) ; 34 void print( ostream & s ) ; 35} point2d ; 36 37// voglio ora definire la somma di due punti 38// point2d = point2d + point2d ; 39point2d operator + ( point2d const & a, point2d const & b ) ; 40 41// voglio ora definire la differenza di due punti 42// point2d = point2d - point2d ; 43point2d operator - ( point2d const & a, point2d const & b ) ; 44 45// voglio ora definire la differenza di due punti 46// point2d = point2d - point2d ; 47point2d operator * ( point2d const & a, point2d const & b ) ; 48 49// voglio ora definire la differenza di due punti 50// point2d = point2d - point2d ; 51point2d operator / ( point2d const & a, point2d const & b ) ; 52 53// voglio ora definire la differenza di due punti 54// point2d = point2d - point2d ; 55double operator ^ ( point2d const & a, point2d const & b ) ; 56 57// per la stampa definisco l'operatore << 58inline 59ostream & 60operator << ( ostream & s, point2d const & a ) 61{ s << "[" << a.x << "," << a.y << "]" ; return s ; } 62 63#endif
File ex024a.cc
1/* 2 * Strutture con metodi 3 */ 4 5#include "ex024.h" 6 7// definizione dei metodi 8 9void 10point2d::init() { 11 x = y = 0 ; 12} 13 14void 15point2d::set( double const x, double const y ) { 16 // this e' puntatore a se stesso cioe' la struttura stessa 17 // x o this -> x e' la stessa cosa a meno x non sia un argomento 18 // o variabile dichiarata nel metodo per cui diventa 19 // inaccessibile. 20 this -> x = x ; 21 this -> y = y ; 22} 23 24void 25point2d::move_x( double const tx ) { 26 x += tx ; 27} 28 29void 30point2d::move_y( double const ty ) { 31 y += ty ; 32} 33 34void 35point2d::rotate( double alpha, // angolo in radianti (senso antioario) 36 point2d & center // centro di rotazione 37 ) { 38 double dx = x - center . x ; 39 double dy = y - center . y ; 40 double dst = sqrt( dx*dx+dy*dy ) ; 41 double beta = atan2( dy, dx ); // dato il vettore (x,y) atan2(y,x) restituisce 42 // il suo angolo in radianti 43 x = center.x + dst * cos( alpha+beta ) ; 44 y = center.y + dst * sin( alpha+beta ) ; 45} 46 47void 48point2d::print( ostream & s ) { 49 s << "[ " << x << " , " << y << "]" ; 50} 51 52// voglio ora definire la somma di due punti 53// point2d = point2d + point2d ; 54point2d 55operator + ( point2d const & a, point2d const & b ) { 56 point2d a_plus_b ; 57 a_plus_b.x = a.x + b.x ; 58 a_plus_b.y = a.y + b.y ; 59 return a_plus_b ; 60} 61 62// voglio ora definire la differenza di due punti 63// point2d = point2d - point2d ; 64 65point2d 66operator - ( point2d const & a, point2d const & b ) { 67 point2d a_plus_b ; 68 a_plus_b.x = a.x - b.x ; 69 a_plus_b.y = a.y - b.y ; 70 return a_plus_b ; 71} 72 73point2d 74operator * ( point2d const & a, point2d const & b ) { 75 point2d a_plus_b ; 76 a_plus_b.x = a.x * b.x ; 77 a_plus_b.y = a.y * b.y ; 78 return a_plus_b ; 79} 80 81point2d 82operator / ( point2d const & a, point2d const & b ) { 83 point2d a_plus_b ; 84 a_plus_b.x = a.x / b.x ; 85 a_plus_b.y = a.y / b.y ; 86 return a_plus_b ; 87} 88 89double 90operator ^ ( point2d const & a, point2d const & b ) { 91 return a.x * b.y - a.y * b.x ; 92}
File ex024b.cc
1/* 2 * Strutture con metodi 3 */ 4 5/* 6 * In C++ ad una struttura si possono 7 * aggiungere funzioni (chiamati metodi) che 8 * operano sulla stessa. 9 * 10 * Si possono anche definire gli operatori standard + - * / etc 11 * come operano sulla struttura 12 */ 13 14#include "ex024.h" 15 16int 17main() { 18 point2d a, b, c, d ; 19 20 a . set( 1, 2) ; 21 b . set( 2, .1) ; 22 c . set( -1, -3) ; 23 d . set( 0.3, 1) ; 24 25 a . move_x( 12) ; 26 b . move_y( -3) ; 27 28 a . rotate( 0.31, b ) ; 29 30 31 d = a+b-c/a; 32 33 // se invecie che gli operatori avessi usato funzioni 34 // serebbe stato uno "statement" tipo: 35 // d = somma( a, differenza(b,c)) 36 37 cout << "a = " ; a . print( cout ) ; cout << "\n" ; 38 cout << "b = " ; b . print( cout ) ; cout << "\n" ; 39 cout << "c = " ; c . print( cout ) ; cout << "\n" ; 40 cout << "d = " << d << "\n" ; 41 cout << "a^b = " << (a^b) << "\n" ; 42 43 /* 44 * Anche se l'approccio e' valido si puo' fare di meglio in C++ 45 */ 46 47 return 0 ; 48}
File ex025.h
1/* 2 * Strutture con metodi 3 */ 4 5 6/* 7 * In C++ ad una struttura si possono 8 * aggiungere funzioni (chiamati metodi) che 9 * operano sulla stessa. 10 * 11 * Si possono anche definire gli operatori standard + - * / etc 12 * come operano sulla struttura 13 */ 14#ifndef EX025_H 15#define EX025_H 16 17#include <iostream> 18#include <cmath> 19 20using namespace std ; 21 22/* definisco la struttura punto2d */ 23typedef struct point2d { 24 double x, y ; 25 /* Invecie che definire delle funzioni esterne, definisco dei 26 metodi interni alla struttura */ 27 // definisco solo i prototipi 28 void set( double const x, double const y ) ; 29 30 inline 31 point2d & operator += ( point2d const & b ) { 32 cout << "USO OPERATORE += INTERNO\n" ; 33 x += b.x ; y += b.y ; 34 return *this ; 35 } 36 37} point2d ; 38 39// voglio ora definire la somma di due punti 40// point2d = point2d + point2d ; 41point2d operator + ( point2d const & a, point2d const & b ) ; 42 43// voglio ora definire la differenza di due punti 44// point2d = point2d - point2d ; 45point2d operator - ( point2d const & a, point2d const & b ) ; 46 47// voglio ora definire la differenza di due punti 48// point2d = point2d - point2d ; 49point2d operator * ( point2d const & a, point2d const & b ) ; 50 51// voglio ora definire la differenza di due punti 52// point2d = point2d - point2d ; 53point2d operator / ( point2d const & a, point2d const & b ) ; 54 55// voglio ora definire la differenza di due punti 56// point2d = point2d - point2d ; 57double operator ^ ( point2d const & a, point2d const & b ) ; 58 59inline 60bool 61operator == ( point2d const & a, point2d const & b ) { 62 return a.x == b.x && a.y == b.y ; 63} 64// gli operatori >= <= > < non hanno senso sui punti 65 66inline 67point2d & operator += ( point2d & a, point2d const & b ) { 68 cout << "USO OPERATORE += ESTERNO\n" ; 69 a.x += b.x ; a.y += b.y ; 70 return a ; 71} 72 73// per la stampa definisco l'operatore << 74inline 75ostream & 76operator << ( ostream & s, point2d const & a ) 77{ s << "[" << a.x << "," << a.y << "]" ; return s ; } 78 79#endif
File ex025a.cc
1/* 2 * Strutture con metodi 3 */ 4 5#include "ex025.h" 6 7// definizione dei metodi 8 9void 10point2d::set( double const x, double const y ) { 11 // this e' puntatore a se stesso cioe' la struttura stessa 12 // x o this -> x e' la stessa cosa a meno x non sia un argomento 13 // o variabile dichiarata nel metodo per cui diventa 14 // inaccessibile. 15 this -> x = x ; 16 this -> y = y ; 17} 18 19// voglio ora definire la somma di due punti 20// point2d = point2d + point2d ; 21point2d 22operator + ( point2d const & a, point2d const & b ) { 23 point2d a_plus_b ; 24 a_plus_b.x = a.x + b.x ; 25 a_plus_b.y = a.y + b.y ; 26 return a_plus_b ; 27} 28 29// voglio ora definire la differenza di due punti 30// point2d = point2d - point2d ; 31 32point2d 33operator - ( point2d const & a, point2d const & b ) { 34 point2d a_plus_b ; 35 a_plus_b.x = a.x - b.x ; 36 a_plus_b.y = a.y - b.y ; 37 return a_plus_b ; 38} 39 40point2d 41operator * ( point2d const & a, point2d const & b ) { 42 point2d a_plus_b ; 43 a_plus_b.x = a.x * b.x ; 44 a_plus_b.y = a.y * b.y ; 45 return a_plus_b ; 46} 47 48point2d 49operator / ( point2d const & a, point2d const & b ) { 50 point2d a_plus_b ; 51 a_plus_b.x = a.x / b.x ; 52 a_plus_b.y = a.y / b.y ; 53 return a_plus_b ; 54} 55 56double 57operator ^ ( point2d const & a, point2d const & b ) { 58 return a.x * b.y - a.y * b.x ; 59}
File ex025b.cc
1/* 2 * Strutture con metodi 3 */ 4 5/* 6 * In C++ ad una struttura si possono 7 * aggiungere funzioni (chiamati metodi) che 8 * operano sulla stessa. 9 * 10 * Si possono anche definire gli operatori standard + - * / etc 11 * come operano sulla struttura 12 */ 13 14#include "ex025.h" 15 16int 17main() { 18 point2d a, b, c, d ; 19 20 a . set( 1, 2) ; 21 b . set( 2, .1) ; 22 c . set( -1, -3) ; 23 d . set( 0.3, 1) ; 24 25 26 // a += b ; 27 // avendo definito += sia come operatore esterno alla struttura 28 // che interno alla struttura, e' ambiguo 29 a . operator += ( b ) ; // scelgo esplicitamente l'operatore interno 30 a = operator += ( a, b ) ; // scelgo esplicitamente l'operatore esterno 31 d = a+b-c/a; 32 33 // se invecie che gli operatori avessi usato funzioni 34 // serebbe stato uno "statement" tipo: 35 // d = somma( a, differenza(b,c)) 36 37 cout << "a = " << a << "\n" 38 << "b = " << b << "\n" 39 << "c = " << c << "\n" 40 << "d = " << d << "\n" 41 << "a^b = " << (a^b) << "\n" ; 42 43 /* 44 * Anche se l'approccio e' valido si puo' fare di meglio in C++ 45 */ 46 47 return 0 ; 48}