Se definisci operator<<
come funzione membro, avrà una sintassi scomposta diversa rispetto a quella utilizzata per non membro operator<<
. Un non membro operator<<
è un operatore binario, dove un membro operator<<
è un operatore unario.
// Declarations
struct MyObj;
std::ostream& operator<<(std::ostream& os, const MyObj& myObj);
struct MyObj
{
// This is a member unary-operator, hence one argument
MyObj& operator<<(std::ostream& os) { os << *this; return *this; }
int value = 8;
};
// This is a non-member binary-operator, 2 arguments
std::ostream& operator<<(std::ostream& os, const MyObj& myObj)
{
return os << myObj.value;
}
Allora ... come li chiami davvero? Gli operatori sono strani in qualche modo, ti sfiderò a scrivere la operator<<(...)
sintassi nella tua testa per dare un senso alle cose.
MyObj mo;
// Calling the unary operator
mo << std::cout;
// which decomposes to...
mo.operator<<(std::cout);
Oppure puoi provare a chiamare l'operatore binario non membro:
MyObj mo;
// Calling the binary operator
std::cout << mo;
// which decomposes to...
operator<<(std::cout, mo);
Non hai l'obbligo di fare in modo che questi operatori si comportino in modo intuitivo quando li trasformi in funzioni membro, potresti definire lo operator<<(int)
spostamento a sinistra di alcune variabili membro se lo desideri, capire che le persone potrebbero essere un po 'colte alla sprovvista, non importa quanti commenti potresti Scrivi.
Quasi finalmente, ci possono essere momenti in cui entrambe le scomposizioni per una chiamata operatore sono valide, potresti finire nei guai qui e rimanderemo quella conversazione.
Infine, nota quanto potrebbe essere strano scrivere un operatore membro unario che dovrebbe assomigliare a un operatore binario (poiché puoi rendere gli operatori membri virtuali ..... anche tentando di non devolvere e correre lungo questo percorso ... )
struct MyObj
{
// Note that we now return the ostream
std::ostream& operator<<(std::ostream& os) { os << *this; return os; }
int value = 8;
};
Questa sintassi irriterà molti programmatori ora ...
MyObj mo;
mo << std::cout << "Words words words";
// this decomposes to...
mo.operator<<(std::cout) << "Words words words";
// ... or even further ...
operator<<(mo.operator<<(std::cout), "Words words words");
Nota come cout
è il secondo argomento della catena qui .... strano vero?