Il problema con questa configurazione è che l'operatore < < definito sopra è una funzione libera, che non può essere virtuale (non ha oggetto ricevitore). Per rendere la funzione virtuale, deve essere definita come membro di una classe, il che è problematico qui perché se si definisce l'operatore < < come membro di una classe, gli operandi saranno nell'ordine errato:
class MyClass {
public:
virtual ostream& operator<< (ostream& out) const;
};
significa che
MyClass myObject;
cout << myObject;
non si compila, ma
MyClass myObject;
myObject << cout;
sarà legale.
Per risolvere questo problema, è possibile applicare il Teorema fondamentale dell'ingegneria del software: qualsiasi problema può essere risolto aggiungendo un altro livello di riferimento indiretto. Piuttosto che fare operatore < < virtuale, considerare l'aggiunta di una nuova funzione virtuale per la classe che assomiglia a questo:
class MyClass {
public:
virtual void print(ostream& where) const;
};
Poi, definire operatore < < come
ostream& operator<< (ostream& out, const MyClass& mc) {
mc.print(out);
return out;
}
In questo modo, l'operatore < < la funzione libera ha l'ordine dei parametri corretto, ma il comportamento dell'operatore < < può essere personalizzato in sottoclassi.
Spero che questo aiuti!
grazie è molto utile. ho pensato a questa soluzione, ma ho pensato che forse c'è un altro modo in cui non lo so più facile per l'implementazione. –
* "qualsiasi problema può essere risolto aggiungendo un altro livello di riferimento indiretto" * - ricorda, qualsiasi problema eccetto il problema di troppi livelli di riferimento indiretto;) – Kos
@Kos: No, no. Finché l'hai dichiarato "indiretto senza segno", devi solo aggiungere sempre più indiretta e il problema si risolverà da solo quando cambi il valore di –