Costruttori/distruttori. Sovraccarico degli operatori. Costruttori

Costruttori/distruttori.
Sovraccarico degli operatori.
Ugo de'Liguoro - Informatica 2. Sovraccarico
Costruttori/distruttori
Quando un oggetto viene
allocato viene eseguita una
routine di inizializzazione: il
costruttore. Quando viene
deallocato si esegue un
distruttore
Ugo de'Liguoro - Informatica 2. Sovraccarico
Necessità di un cotruttore
Ratio::Ratio(int n, int d)
{
Assign(n, d);
}
void Ratio::Assign (int n, int d)
{
if (d != 0) {num = n, den = d;}
else cout << "divisione per 0" << endl;
}
Il costruttore mantiene l’invariante “il
denominatore è sempre ≠ 0”
Ugo de'Liguoro - Informatica 2. Sovraccarico
1
Costruttori e oggetti statici
class Ratio {
costruttore
public:
Ratio (int n=0, int d=1) { num = n; den = d;}
private: ...
};
default
Ratio a (7, 4); // a vale 7/4
Ratio b (7);
// b vale 7/1
Ratio c;
// c vale 0/1
Ugo de'Liguoro - Informatica 2. Sovraccarico
Oggetti e valori
Un oggetto può essere il valore di
una funzione o di un metodo
Già l’ANSI-C
consente di ritornare
strutture
Ratio Ratio::Sum (Ratio r)
{
Ratio q (num*r.den+den*r.num,den*r.den);
return q;
}
Ugo de'Liguoro - Informatica 2. Sovraccarico
Costruttore di copia
class Ratio {
Costruttore di copia (= default)
public:
Ratio (int n=0, int d=1) { num = n; den = d;}
Ratio (const Ratio& r)
{ num = r.num; den = r.den;}
private: ...
};
Ratio a (2,3);
Ratio b(a); // b è un clone di a
Ugo de'Liguoro - Informatica 2. Sovraccarico
2
Costruttore di copia
Il costruttore di copia viene invocato quando:
• si definisce un oggetto in termini di uno già
definito: Ratio r Ratio(q);
• Nelle assegnazioni o inizializzazioni:
Ratio r = q;
• si passa una argomento per valore ad una
funzione
• quando una funzione restituisce un valore
Ugo de'Liguoro - Informatica 2. Sovraccarico
Costruttore di copia
Il costruttore di copia viene invocato quando:
• …
• si passa una argomento per valore ad una
funzione
Ratio (const Ratio& r)
Il passaggio per riferimento è
allora necessario
Ugo de'Liguoro - Informatica 2. Sovraccarico
Polinomi
class Polinomio {
public:
Polinomio (int degree, double c[]);
// Pre: c[] ha dimensione >= degree + 1
// Post: genera il polinomio di grado degree e
// coefficienti c[0..degree] (in ordine decr. di grado)
Polinomio (const Polinomio& p); // costr. di copia
~Polinomio (); // distruttore
private:
double* coefficienti;
...
Ugo de'Liguoro - Informatica 2. Sovraccarico
3
Polinomi
Polinomio q (p);
Questo si otterrebbe
usando il costruttore di
copia di default
Ugo de'Liguoro - Informatica 2. Sovraccarico
Polinomi
Polinomio::Polinomio (const Polinomio& p)
{
degree = p.degree;
coeff = new double[degree + 1];
for (int i = 0; i < degree + 1; i++)
coeff[i] = p.coeff[i];
}
Polinomio q (p);
p
q
Ugo de'Liguoro - Informatica 2. Sovraccarico
Sovraccarico degli operatori
Il C++ consente di ridefinire i suoi operatori:
Ratio p(2,3), q(1,4);
Ratio r = p + q;
Questa è una somma di
razionali
class Ratio { ...
public:
Ratio operator+ (const Ratio& r); ... }
Ratio Ratio::operator+ (const Ratio& r)
{
}
return Ratio(num * r.den + r.num * den, den * r.den);
Ugo de'Liguoro - Informatica 2. Sovraccarico
4
Sovraccarico degli operatori
class Ratio { ...
public:
Ratio operator+ (const Ratio& r); ... }
Ratio Ratio::operator+ (const Ratio& r)
{
Funzione membro
return Ratio(num * r.den + r.num * den, den * r.den);
}
Ratio p(1,2), q(2,3);
Ratio r = p + q; // equivale a r = p.operator+(q)
Ugo de'Liguoro - Informatica 2. Sovraccarico
Sovraccarico degli operatori
class Ratio { ...
public:
Ratio operator+ (const Ratio& r); ... }
Ratio Ratio::operator+ (const int n)
{
return Ratio(num * n, den);
}
Ratio p(1,2); int n = 3;
Ratio r = p + n; // equivale a r = p.operator+(n)
Ratio r = n + p; // ERRORE: n.operator+(q) non è definito
Ugo de'Liguoro - Informatica 2. Sovraccarico
Sovraccarico degli operatori
class Ratio { ...
public:
Ratio operator+ (const Ratio& r); ... }
friend Ratio Ratio::operator+ (const int n, const Ratio& r))
{
return Ratio(num * n, den);
}
Funzione friend
Ratio p(1,2); int n = 3;
Ratio r = n + p; // OK
Se il primo parametro non appartiene
alla classe la funzione non può essere
membro
Ugo de'Liguoro - Informatica 2. Sovraccarico
5
Sovraccarico degli operatori
friend ostream& operator<< (ostream& os, const Ratio& r);
…
ostream& operator<< (ostream& os, const Ratio& r)
{
if (r.den != 1) os << r.num << '/' << r.den;
else os << r.num;
return os;
Tipico esempio: la
ridefinizione dell’ I/O
cout << r; // r è di classe Ratio
Ugo de'Liguoro - Informatica 2. Sovraccarico
Sovraccarico di =
Polinomio& Polinomio::operator= (const Polinomio& p)
{
if (&p != this)
if
{
// non esegue se c'è autorif.
(degree != p.degree) {
// la dimensione di coeff è diversa
delete [] coeff;
// libera la memoria occupata dal vecchio
degree = p.degree;
coeff = new Ratio[degree + 1];
}
for (int i = 0; i < degree + 1; i++)
// copia dei coefficienti
coeff[i] = p.coeff[i];
}
return *this;
}
// consente assegnazioni come p = q = f;
Ugo de'Liguoro - Informatica 2. Sovraccarico
6