|
|
|
|
Definiremo la classe Point2: |
|
La classe rappresenta i punti del piano. |
|
Si definiscono alcuni operatori di base. |
|
Si parametrizza la classe secondo il tipo
scalare di riferimento (template). |
|
Si accenna ad altre possibili implementazioni. |
|
|
|
|
class Point2 // Intestazione |
|
{ |
|
private: // Dati privati |
|
double v[2]; // Dati della classe |
|
public: // Membri pubblici |
|
//… membri … |
|
}; // Notare il ‘;’ |
|
|
|
Una classe e’ composta da dati e funzioni, sia i
dati che le funzioni possono essere privati o pubblici, vale a dire
visibili dall’utilizzatore della classe. |
|
|
|
|
inline Point2() // Costruttore di default |
|
{ |
|
} |
|
inline Point2( double v0, double v1 ) |
|
{ |
|
v[0] = v0; // Costruttore con |
|
v[1] = v1; // Inizializzazione |
|
} |
|
|
|
I costruttori sono funzioni che vengono chiamate
automaticamente al tempo di creazione di un oggetto; possono avere o non
avere parametri. |
|
|
|
|
inline Point2 & operator= ( const Point2
& p ) |
|
{ |
|
v[0] = p.v[0]; |
|
v[1] = p.v[1]; |
|
return *this; |
|
} |
|
|
|
Note: la stringa ‘operator=‘ è il nome della
funzione. Il tipo del parametro è obbligatorio, come il valore di ritorno
che permette di concatenare le espressioni: a = b = 3; |
|
|
|
|
inline Point2 operator+ (const Point2 & p)
const |
|
{ |
|
return Point2( v[0]+p.v[0], v[1]+p.v[1] ); |
|
} |
|
|
|
Note: il primo operando dell’operatore somma è
l’oggetto in questione (this). L’operatore è const (non modifica
l’oggetto). Si utilizza il costruttore con parametri per costruire “al
volo” il valore di ritorno. Il parametro p è passato per riferimento per
motivi di efficienza. |
|
|
|
|
inline void show() const |
|
{ |
|
cout << '[' << v[0] << ','
<< v[1] <<"]\n"; |
|
} |
|
|
|
Metodo per la visualizzazione della classe;
l’oggetto è visualizzato nella forma: [v0,v1]. |
|
|
|
|
|
|
Class Point2 … // Definizione classe |
|
int main() |
|
{ |
|
Point2 a(2,4); // Costr. con iniziliz. |
|
Point2 b(3,2); |
|
Point2 c; // Costruttore default |
|
c = a+b; // Somma ed assegnamento |
|
c.show(); // Visualizzazione |
|
return 0; |
|
} |
|
|
|
|
template <class scalar> class Point2 |
|
{ |
|
private: |
|
scalar v[2]; // Dati |
|
public: |
|
… |
|
}; |
|
|
|
Si parametrizza la classe secondo il tipo
scalare, l’implementazione rimane (quasi) invariata. |
|
|
|
|
… |
|
Point2<float> p( 3.4 , 2.7 ); |
|
Point2<int> q( 3,2 ); |
|
Point2<complex> z; |
|
… |
|
|
|
Specificando il parametro template di possono
dichiarare punti formati da float, interi etc. |
|
|
|
|
inline bool operator== ( const Point2 & p )
const |
|
{ |
|
return v[0]==p.v[0] && v[1]==p.v[1]; |
|
} |
|
inline bool operator!= ( const Point2 & p )
const |
|
{ |
|
return v[0]!=p.v[0] || v[1]!=p.v[1]; |
|
} |
|
|
|
L’operatore di confronto è una funzione booleana
(costante). |
|
|
|
|
inline scalar& operator[] (const int i) |
|
{ |
|
return v[i]; |
|
} |
|
inline const scalar& operator[] (const int
i) const |
|
{ |
|
return v[i]; |
|
} |
|
|
|
L’operatore [] permette di accedere alle
componenti. La versione costante viene utilizzata in lettura. |
|
|
|
|
Point2<double> a(1,2); |
|
Point2<double> b(5,7); |
|
double x; |
|
|
|
a[0] = 9; // Accesso con operatore [] |
|
x = (a+b)[1]; // Accesso con op. costante |
|
|
|
Il compilatore utilizza l’operatore [] standard
o costante a seconda dei casi: il risultato della somma fra a e b e’
costante e non potrebbe essere acceduto dall’operatore [] standard. |
|
|
|
|
inline scalar& operator[] (const int i) |
|
{ |
|
assert(i>=0 && i<2); // Controllo
in debug |
|
return v[i]; |
|
} |
|
inline const scalar& operator[] (const int
i) const |
|
{ // Controllo esplicito |
|
if(i<0 || i>=2) return v[0]; |
|
else
return v[i]; |
|
} |
|
|
|
|
class CPoint : public Point2<double> |
|
{ |
|
public: |
|
Color c; |
|
inline CPoint() {} |
|
inline CPoint( double x, double y, Color nc ) |
|
: Point2<double>(x,y) |
|
{ |
|
c = nc; |
|
} }; |
|
Derivazione della sottoclasse punto colorato. |
|
|
|
|
L’implementazione finora vista non e’ la
migliore. |
|
Esiste un’altra tecnica, piu’ efficiente, che fa
utilizzo della creazione dinamica di tipi per la valutazione statica delle
espressioni. |
|
|
|
J. Blinn, Optimizing C++ Vector Expressions,
IEEE Computer Graphics and Applications, July-August 2000, pg. 97-103. |
|
|
|
|
Scrivere l’operatore sottrazione: a = b-c; |
|
Scrivere il prodotto scalare: a = b*c; |
|
Scrivere l’operatore meno unario: a = -b; |
|
Scrivere il prodotto per scalare a destra,
esempio: a = b*3.0; |
|
Scrivere il prodotto per scalare a sinistra,
esempio: a = 3.0*b; (*) |
|
|
|
|
|
(*) Esercizio impegnativo |
|
|
|
|
Claudio Rocchini |
|
|
|
email: rocchini@iei.pi.cnr.it |
|
web
: http://vcg.iei.pi.cnr.it/~rocchini |
|
tel. : 050-3152926 |
|
|
|
Ufficio: Istituto Elaborazione Informazione,
CNR, Area della ricerca di Pisa, S. Cataldo Pisa. |
|
|
|