#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;