PDA

Visualizza la versione completa : [C++] Overload operatore <<


GrG
17-06-2013, 23:31
Buonasera,

avevo un altro dubbio (che credo sia abbastanza rapido)..

Sto definendo una classe che mi modella un oggetto persona, solo che ho la necessità di ridefinire l'operatore << per fare in modo di ritornare una stringa che contenga il nome della persona con a fianco l'età (che sono due variabili private della classe)

Qualcosa del tipo:


string& Persona::operator<<(string& s)
{
s = this->nome+" "+this->eta+" "+s;
return s;
}



Solo che in C++ non c'è una conversione implicita da intero a stringa.. considerando che sarebbe meglio non usare itoa e che non posso usare:
string eta;
eta << this->eta;
eta.str();

visto che g++ mi dice che non trova l'operatore<<:
"error: no match for ‘operator<<’ in ‘eta << ((Persona*)this)->Persona::eta’"
Ho importato le seguenti librerie:
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

Il fatto è che g++ non mi va a cercare l'operatore << in std ma nella stessa classe.. come posso fare? Grazie

MItaly
17-06-2013, 23:37
Normalmente non si usa l'operatore << sulle stringhe, ma sugli stream, per cui il tuo operator<< dovrebbe essere:


std::ostream & Persona::operator<<(std::ostream & os)
{
return os<<nome<<" "<<eta<<" ";
}


Sarà poi il chiamante ad usarlo eventualmente su uno stringstream per ricavarne una stringa:


std::ostringstream os;
Persona p;
// ...
os<<p;
std::string s=os.str();

(per l'ostringstream vedi qui (http://www.cplusplus.com/reference/sstream/ostringstream/))

MItaly
17-06-2013, 23:56
Ah tra l'altro nel copia-incolla mi era sfuggito un passaggio fondamentale... non puoi definire operator<< come membro della classe, dato che il primo operando di << è lo stream, e non la tua classe (in altre parole: negli operatori ridefiniti come membri della classe, il primo operando è *this, e quindi necessariamente ha il tipo della classe).

Ergo, devi definire l'operatore come funzione libera:


std::ostream & operator<<(const Persona & p, std::ostream & os)
{
return os<<p.nome<<" "<<p.eta<<" ";
}

Se nome ed eta sono private, dovresti rendere la funzione in questione friend, oppure fornire dei metodi getter (cosa che potrebbe avere più senso).

GrG
18-06-2013, 00:08
mm.. quando compilo g++ mi dice:

"error: ‘std::ostream& Persona::operator<<(const Persona&, std::ostream& )’ must take exactly one argument"

Non capisco bene dov'è il problema..

p.s Ho visto su internet che in genere si usa ( std::ostream&, const Persona& ) ma comunque anche se cambio l'ordine l'errore è sempre lo stesso

EDIT:
Usando:


ostream& Persona::operator<<(ostream& os)
{
return os << this->nome << " "<< this->eta << " ";
}


e usando:
oggetto_persona << oggetto_ostringstream;

funziona!

ma io vorrei che la relazione sia al contrario, cioè vorrei avere:
oggetto_ostringstream << oggetto_persona;

ma con lo stesso risultato, come posso fare?

EDIT:
Anzi no va bene anche così, grazie mille!!

MItaly
18-06-2013, 00:38
Originariamente inviato da GrG

ma io vorrei che la relazione sia al contrario, cioè vorrei avere:
oggetto_ostringstream << oggetto_studente;
Hai ragione, e io dovrei andare a dormire perché continuo a scrivere cavolate. :D Nell'ultimo blocco di codice che ho scritto i due argomenti vanno invertiti:


std::ostream & operator<<(std::ostream & os, const Persona & p)
{
return os<<p.nome<<" "<<p.eta<<" ";
}

Loading