Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Операторы перенаправления потока


Автор: hoz 27.6.2013, 23:42
Я приступил к изучению С++ после Си. Там всё писал функциями и всё последовательно. Здесь же сразу бросились в глаза некоторые моменты, которые мне вообще не понятны, при прочтении книги Джесс Либерти. Освой самостоятельно С++ за 21 день.

1. Данные операторы перенаправления потока являются операторами командной строки или языка С++ ?
2. В книге есть такой пример:

Код

#include <iostream.h>
int main()
{
    int x = 5;
    int y = 7;
    cout << "\n";
    cout << x + y << " " <<  x * y;
    cout << "\n";
    return 0;
}


Я б изначально как обычно прочитал бы код последовательно. Записать x + y в cout. А дальше " " записаться должно в x + y; и т.д.
 Но Ответ верный такой: Выводится сумма и произведение переменных x и y и между ними пробел. Код читается компилятором слева направо что-ли?
Дело в том, что я б написал его так:


Код

cout << "\n";
cout << x + y;
cout << " ";
cout << x * y;
cout << "\n";


Так, всё было бы логично, и последовательно. А в книге, приведён вариант, который выше я написал. Почему так?

Автор: bsa 28.6.2013, 08:29
В С++ можно переопределять стандартные операторы. В частности, есть перегрузка оператора << для объектов класса ostream. В итоге cout << A << B << C превращается в operator<<(operator<<(operator<<(cout, A), B), C). Так как объявление этого оператора имеет вид: ostream& operator<<(ostream& stream, Type value). Т.е. он возвращает ссылку на объект потока,  в итоге следущий оператор тоже применяется к потоку и т.д.

Добавлено через 3 минуты и 54 секунды
Кстати, при изучении с++ рекомендуется забыть си. Потому что в с++ используются другие подходы к программированию, а знание си сильно усложняет восприимчивость нового. Особенно, когда оно "противоречит" логике (на самом деле не противоречит, просто логика другого порядка).

Автор: hoz 28.6.2013, 14:32
Цитата(bsa @  28.6.2013,  08:29 Найти цитируемый пост)
 Так как объявление этого оператора имеет вид: ostream& operator<<(ostream& stream, Type value)


Вы сделали такой вывод т.к. знаете как работает библиотека iostream ? Изучали её? В книгах по этому поводу вообще ничего особо нет. Хотя в примерах повсеместно в тех же книгах и на просторах интернета используется... Странно..

Автор: feodorv 28.6.2013, 15:46
Цитата(hoz @  28.6.2013,  15:32 Найти цитируемый пост)
Вы сделали такой вывод т.к. знаете как работает библиотека iostream ? Изучали её?

Ну да. Всё это в достаточной степени стандартизировано и называется стандартной библиотекой (то есть эта библиотека как таковая не является частью языка, но она очень удобна).
См. http://www.cplusplus.com/reference/istream/iostream/, например.

Цитата(hoz @  28.6.2013,  15:32 Найти цитируемый пост)
В книгах по этому поводу вообще ничего особо нет.

Наверняка в каких либо главах описываются операторы ввода-вывода << и >>. 

Автор: bsa 28.6.2013, 16:14
hoz, довольно сложно автору книги объяснить все внутренности языка, которые используются при написании простейшей программы Hello, world! Если он это начнет делать, то читатель выкинет эту книгу. Поэтому, обычно, авторы не углубляются на первых страницах.
Чтобы ты ощутил всю глубину проблемы, то объявление класса выглядит так:
Код
namespace std {
...
template< 
    class CharT, 
    class Traits = std::char_traits<CharT>
> class basic_ostream : virtual public std::basic_ios<CharT, Traits>
{
...
};
...
typedef basic_ostream<char> ostream;
...
}
Тут и виртуальное наследование, и шаблоны, и пространства имен... Ты все еще точно хочешь узнать, как оно работает изнутри? Или может быть все-таки эту "фигню" отложить на годик? Я считаю, лучше отложить. Читай книгу и не заморачивайся внутренним устройством. Автор плавно должен подвести к этому.

Автор: akizelokro 29.6.2013, 17:44
Потому что оператор << , как и все операторы в С++, с чем-то взаимодействует.
Здесь ты как бы видишь пример аналогии интерфейса, позволяющего осуществлять взаимодействие с некоторыми объектами.
А у объектов есть свои свойства, от которых никуда не деться.
В данном случае происходит вывод на стандартное устройство (вывода). Который работает по принципу FIFO (первым пришёл - первым ушёл).
Если бы производилась с помощью этого оператора запись в стек, который действует по принципу LIFO (последним пришёл - первым ушёл), то обратная последовательность была бы вполне к месту.

Здесь оператор "<<" никоим образом не относится к порядку передачи данных из объекта в объект, а показывает к какому объекту данные от какого движутся. А дальше уже вступают в силу свойства самих объектов.

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//object-id51cca4526ccc197429000002#findElement_E7045_51cef2b46ccc19ea7b001ad3_0

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)