Каноническая реализация оператора вывода для любого типа T
такова:
std::ostream& operator<<(std::ostream& os, const T& obj)
{
os << obj.get_data1() << get_data2();
return os;
}
Обратите внимание, что операторы выходного потока обычно не являются функциями-членами. (Это потому, что для того, чтобы бинарные операторы были функциями-членами, они должны быть членами типа их левого аргумента. Однако это поток, а не ваш собственный тип. Существует несколько перегрузок operator<<()
для некоторых встроенных -ins, которые являются членами класса потока вывода.)
Поэтому, если не все данные T
общедоступны, этот оператор должен быть другом T
class T {
friend std::ostream& operator<<(std::ostream&, const T&);
// ...
};
или оператор вызывает публичную функцию, которая выполняет потоковую передачу:
class T {
public:
void write_to_stream(std::ostream&);
// ...
};
std::ostream& operator<<(std::ostream& os, const T& obj)
{
obj.write_to_stream(os);
return os;
}
Преимущество последнего заключается в том, что функция-член write_to_stream()
может иметь значение virtual
(и чистая), что позволяет осуществлять потоковую передачу полиморфных классов.
Если вы хотите быть модным и поддерживать всевозможные потоки, вам придется шаблонизировать это:
template< typename TCh, typename TTr >
std::basic_ostream<TCh,TTr>& operator<<(std::basic_ostream<TCh,TTr>& os, const T& obj)
{
os << obj.get_data1() << get_data2();
return os;
}
(Шаблоны, однако, не работают с виртуальными функциями.)