Примечание: Возможно, вы захотите взглянуть на FAQ по перегрузке оператора .
Бинарные операторы могут быть либо членами класса своего левого аргумента, либо свободными функциями. (Некоторые операторы, такие как присваивание, должны быть членами.) Поскольку левый аргумент оператора потока является потоком, операторы потока должны быть либо членами класса потока, либо свободными функциями. Канонический способ реализации operator<<
для любого типа таков:
std::ostream& operator<<(std::ostream& os, const T& obj)
{
// stream obj's data into os
return os;
}
Обратите внимание, что не функция-член. Также обратите внимание, что он принимает объект для потоковой передачи по ссылке const
. Это потому, что вы не хотите копировать объект для потоковой передачи и не хотите, чтобы потоковая передача также изменяла его.
Иногда вы хотите передавать потоковые объекты, внутренние объекты которых недоступны через открытый интерфейс их класса, поэтому оператор не может получить к ним доступ. Тогда у вас есть два варианта: либо поместить открытый член в класс, который выполняет потоковую передачу
class T {
public:
void stream_to(std::ostream&) const {os << obj.data_;}
private:
int data_;
};
и позвоните по этому номеру у оператора:
inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
obj.stream_to(os);
return os;
}
или сделать оператор friend
class T {
public:
friend std::ostream& operator<<(std::ostream&, const T&);
private:
int data_;
};
чтобы получить доступ к закрытым частям класса:
inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
os << obj.data_;
return os;
}