Newsgroup: it.comp.lang.c++
Titolo: Classe che accetti ostream

Salve, sto tentando di costruirmi una classe verso la quale poter
rigirare lo stream out.
Cioè se volessi creare una mia classe MyClass in modo tale da poter
fare questo:
MyClass obj;
std::string username;
int age;
obj << "Ciao" << username << " come va? So che hai " << age << "
anni.";
Cioè la classe MyClass dovrebbe ricevere dello stream in questo modo e
collezionarlo in una variabile di testo.
Ho cercato l'overload dell'operatore << ma non ne sono venuto a capo.
Anzitutto, è possibile? Continuo a cercare qualche guida in giro?
Oppure non è possibile e mi tocca fermarmi e pensare ad un'altra
soluzione?

 Ho cercato l'overload dell'operatore<<  ma non ne sono venuto a capo.
mi risulta che possa essere overloaded ... domanda banale : 
ti sei ricordato di restituire una reference (e una 
reference valida) come valore di ritorno, vero ? (senza 
offesa eh) ... In caso di si, magari posta l'intelaiatura 
del codice
P.S. esistono ancora quei bizzarri oggetti tipo iomanip 
prefabbricati, che forse potevano limitarti il problema ?
ciao
Soviet


No non ho scritto assolutamente nulla.
Non so proprio come iniziare, da quel punto di vista.
In genere l'overload non mi risulta complitato, e mi risulta anche
intuitivo capire cosa restituire.
Ma il fatto di voler effettuare uno stream verso la mia classe, come
va overloadato?
class MyClass
{
  private:
    std::string theText;
  public:
    ???
}
Anzitutto, l'overload dell'operatore << verso un oggetto della mia
classe, cosa deve restituire??? Un const reference a...?


No. Puoi accettare in ingresso (anzi estende il range) un 
CONST Ostream & (o CONST Istream &) al posto di un parametro 
copiato per valore, il che incrementa le performance per 
oggetti di difficile stima dell'overspace, come uno stream.
Ma siccome vuoi che il tuo operatore sia concatenabile 
(inciso : nn so se si possa modificare anche l'associatività 
destra sinistra, ma non credo, così come la priorità di 
valutazione ... restano cmq le parentesi per prevalere in 
casi dubbi), allora il tuo operatore deve essere un LVALUE, 
per cui un reference NON CONST.
In particolare un Ostream & (o Istream &), in cui fai 
passare attraverso la reference al sottostante.
P.S. non ho voglia di tentare di scrivere qualcosa ergo non 
so se vedo giusto. Ma se passi fuori come non const la 
reference allo stesso flusso del parametro passato come 
const, allora da qualche parte dovrai fare una porcata tipo 
un const_cast. Era un suggerimento per alleviare i controlli 
sui parametri passati. Se non vuoi fare la porcata, allora 
passa anche in ingresso una reference non const e sei apposto.
Il codice in definitiva passa da destra a sinistra (se 
l'associatività è quella) o viceversa, una reference allo 
stream dentro e fuori l'operator >> o <<, e nel tempo che 
sta dentro il codice, ci scrive qualcosa, come il paramentro 
a sinistra (o rispett. a destra).
Ovviamente dovrai fare o tante versioni specifiche (tipo per 
stringa, interi, float) o dei template. Io sceglierei un 
approccio ibrido, di templatizzare per tipi simili. Tipo 
tutte le stringhe, tutti gli integral, tutti i float ... e 
sugli oggetti non nativi, regolati tu (potresti optare per 
operatori di conversione a stringa interni a dette classi, e 
nelle operazioni di I/O chiamarli per convertire gli oggetti 
complessi a stringa).
Ovviamente se associa verso destra, il PRIMO oggetto della 
riga deve essere un vero Ostream & (o Istream &), che 
propaga la reference ai tipi vari verso destra).
Se associa verso sinistra, l'ultimo item deve essere la 
reference.
In effetti mi pare che sia la prima, dato che CIN e COUT 
compaiono a inizio riga a non alla fine.
Con le parentesi puoi prevalere, salvo ingenerare 
inconsistenze tipo ... credo !
cin << ("silly" << "example");
Che non credo fungerebbe, perchè cercherebbe per primo un
char * ????::operator << (char *)
e poi
char * ::operator << (char *)
ossia una versione globale non membro (e non troverebbe alcuna)
ho messo i ???? perchè appunto da che diamine di 
informazione dei due parametri stringa potrebbe mai desumere 
l'oggetto classe in cui cercare ?
Ma non so se ho fatto un esempio giusto, non è facile x me 
pensare di simulare cosa capirebbe il compilatore, non sono 
un compilatore :-)
ciao
Soviet

 Ho cercato l'overload dell'operatore << ma non ne sono venuto a capo.
No, non è questa la strada corretta.
Ciao  Manlio

On 10 Mar, 19:55, Manlio Perillo <manlio_perill...@SPAMlibero.it>
wrote:

Ok grazie, ed approfitto per ringraziare anche Mario che è stato molto
disponibile.
In effetti c'ero arrivato giusto un paio di minuti fa. Mi sono
ricordato che tempo fa, googlando alla ricerca del modo più immediato
per convertire un numero in stringa, veniva consigliato proprio l'uso
di stringstream, al quale si può concatenare pressochè tutto.
Ed il metodo str() poi restituisce la stringa finale.
In effetti forse conviene usare quello, anche se non è propriamente
ciò che volevo ma vabè, si tratta di usare giusto un paio di
istruzioni in più: concatenare allo stream ed invocare il metodo
append(const std::string &text) della mia classe, che poi farà il suo
sporco lavoro.
Grazie ancora!