Perchè a questa funzione viene passato il riferimento di ostream (ostream&) e non semplicemente ostream?
ostream non è copiabile, quindi occorre passare un reference. Tra l'altro in
ostream& operator<<(ostream& os, complesso z)
stai passando complesso per valore, cosa non sbagliata ma se passi un const reference
ostream& operator<<(ostream& os, const complesso& z)
risparmi una copia nello stack della funzione, che in caso di oggetti "grossi" è poco efficente.
Nel caso avessi i valori corrispondenti ai dati della classe come re=2 e im=5.6 quali sarebbero i parametri corrispondenti passati alla funzione operator<< ?
Continuo a non capire che dubbi hai. In questo codice
ostream& operator<<(ostream& os, complesso z)
{
os << '(' << z.reale() << ',' << z.imag() <<')';
return os;
}
il compilatore vede che esiste un operator<< che accetta un oggetto di tipo complesso(e di cui non ha la minima idea di come è fatto).
Nel codice della funzione vede che deve inviare un char, un double, un char, un double, un char a un oggetto di tipo ostream per cui invoca gli appositi overload di ostream per i tipi semplici. Restituisce l'oggetto ostream. Fine.
Poi non comprendo perchè vengono passati due argomenti anziché soltanto la classe, in generale avevo letto che se l'operatore è binario viene passato normalmente un argomento visto che l'istanza della classe è già implicita, mentre se nel caso fosse unario nessun argomento.
Dipende se vuoi l'operatore definito a livello di classe o a livello globale.
http://en.cppreference.com/w/cpp/language/operator_arithmetic
Alle volte è conveniente definirli a livello di classe, alle volte è conveniente definirli a livello globale, altre volte è conveniente definirli in entrambi i modi. Io, per me, se dovessi scrivere una classe complesso, non definirei operator+ a livello di classe, ma solo a livello globale.