Top.Mail.Ru
Ответы

Перегрузка операторов ввода\вывода С++

Предположим, есть класс:
class some_class
{
private:
int a;
int b;
int c;
private:
...//тут какие-нибудь методы;

friend ostream& operator<<(ostream& stream, const some_class& s)

{

stream << s.a<<"\t"<<s.b<<"\t"<<s.c<<endl;

return stream;
}
}
вопросы следующие:
1) почему это friend оператор?
2) зачем нам возвращать stream, если мы принимаем ссылку на него? из-за этого приходится ставить тип возвращаемого значения как ostream&. почему нельзя обойтись void и ничего не возвращать? почему мы не принимаем и не возвращаем НЕ ссылки (то есть просто ostream)?
3) почему мы принимаем экземпляр класса some_class? зачем он нужен? почему нельзя написать "stream<<this->a" и так далее?

Дополнен

"почему нельзя обойтись void и ничего не возвращать?"имеется ввиду, что в качестве возвращаемого значения поставить void, а в скобках оставить ostream& stream

По дате
По рейтингу
Аватар пользователя
Мастер
11лет

1)Функция ввода и функция вывода не могут быть членами класса, потому что если функция operator является членом класса, её левый операнд (передаваемый неявно посредством указателя this) должен быть членом этого класса, который вызывает эту функцию. (дословно цитирую Г. Шилдта)

2)возвращаем ссылку на поток (ostream/istream), для сцепленного вызова. То есть это даёт нам возможность использовать оператор ввода/вывода несколько раз. Это как cout. cout<<a<<b<<c<<endl;
Мы 4 раза использовали операцию "поместить в поток"(<<) - это и есть сцепленный вызов.

3)потому что это следует из определения дружественной функции=) Можно рассмотреть ситуацию на интуитивном уровне: "в функцию вывода передаём объект, который нужно вывести".

Аватар пользователя
Искусственный Интеллект
11лет

1,3) потому что оператор использует поля private класса some_class
2) чтобы можно было делать cout << a << b; чтобы не создавалась копия объекта stream.

А в целом friend - это костыль, который следует использовать либо для скорости, либо для объединения ОО и не-ОО кодов. Если в классе определены публичные inline геттеры для полей a,b,c, то правильнее делать не friend, а использовать именно геттеры.