Почему мы отправляем ссылку на ostream, возражающую против перегрузки ostream?

#c #ostream

Вопрос:

У меня не было интуиции, лежащей в основе такого способа написания реализации, когда мы хотим создать объект ostream для конкретного класса.

 friend ostreamamp; operator<<(ostreamamp; out, Objectamp; obj);
 

У него есть такое применение. При использовании с перегрузкой оператора передается один параметр. Но во время определения мы записали ostreamamp; out в качестве первого параметра. Как передается первый параметр под капотом? Является ли это неявным способом отправки параметров, о которых я не знаю? Наконец, где хранится объект out, на который имеется ссылка? Является ли это глобальной переменной, которая автоматически вызывается перегруженными функциями как таковыми?

 cout << obj
 

Комментарии:

1. Здесь у вас есть ряд основных заблуждений, поэтому я думаю, что лучше всего обратиться к полному объяснению перегрузки операторов в вашем учебнике и тому, как это работает. Что говорится в вашем учебнике по этой теме, и есть ли что-нибудь в объяснении вашего учебника, что вам непонятно?

Ответ №1:

 friend ostreamamp; operator<<(ostreamamp; out, Objectamp; obj);
 

является двоичным оператором (например , - ,…). Он принимает 2 операнда и что-то возвращает.

В данном случае это

 auto result = operand1 << operand2;
 

с result бытием operand1 (оригиналом ostream )

как

 int operator (int operand1, int operand2);
int result = operand1   operand2;
 

И кстати. вы не создаете

объект ostream, зависящий от класса

вы просто определяете оператор потоковой передачи для определенного пользователем типа для работы с потоками. Таким образом, вы определяете, что должно происходить, когда вы пишете такие выражения, как some_ostream << myObject; Он волшебным образом std::ostream не знает, как обращаться с вашим классом, поэтому вам нужно определить этот оператор для вашего типа, чтобы использовать его.

Редактировать:

как указал «S. M.» в комментарии, причина, по которой этот оператор должен возвращать исходный std::ostreamamp; (левый операнд), заключается в том, что вы можете связывать вызовы с этим оператором:

 std::cout << myObj1 << " foo " << myObj2 << " bar ";
 

который можно прочитать как:

 (((std::cout << myObj1) << " foo ") << myObj2) << " bar ";
 

и эквивалентно:

 std::cout << myObj1;
std::cout << " foo ";
std::cout << myObj2;
std::cout << " bar ";
 

И это действительно должно быть

 friend ostreamamp; operator<<(ostreamamp; out, const Objectamp; obj); // const
 

потому что 1. вы не должны манипулировать этим объектом и 2. вы хотите иметь возможность использовать его с const объектами

Комментарии:

1. Спасибо за объяснение. Я предположил, что первый параметр-это тот, к которому мы обращаемся к методу, а не параметр, который используется компилятором для определения правильной реализации, которую мы ищем.

2. @ibrahimcoz Да, это не метод std::ostream , это бесплатная функция.

3. Не хватает одной важной вещи. Возвращаемый поток позволяет использовать поток последовательно, как cout << obj1 << obj2 << std::endl;