Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.08.2017, 10:40   #1
KAMLS
Форумчанин
 
Регистрация: 09.04.2017
Сообщений: 598
По умолчанию Перегрузка cout и cin

Здравствуйте!
Прошу помочь понять поточнее происходящее в программе.
В принципе так-то всё понятно, но хочется более внятно понимать так сказать "закулисную" деятельность)))
Код:
#include<iostream>
using namespace std;
#include<conio.h>
class Distance
{
private:
	int feet;
	float inches;
public:
	Distance():feet(0), inches(0.0)
	{}
	Distance(int ft, float in): feet(ft), inches (in)
	{}
	friend istream& operator >> (istream& s, Distance& d);
	friend ostream& operator << (ostream& s, Distance& d);
};
//----------------------------------------------------------
istream& operator >> (istream& s, Distance& d) интересует эта строка
{
	cout<<"\nВведите футы: ";  s>>d.feet;
	cout<<"\nВведите дюймы: "; s>>d.inches;
	return s;
}
ostream& operator << (ostream& s, Distance& d)
{
	s<<d.feet<<"\'-"<<d.inches<<'\"';
	return s;
}
int main()
{
	setlocale(LC_ALL,"rus");
	Distance dist1, dist2;
	Distance dist3(11, 6.25);
	cout<<"\nВведите два значения расстояний: ";
	cin>>dist1>>dist2;
	cout<<"\ndist1="<<dist1<<"\ndist2="<<dist2;
	cout<<"\ndist3="<<dist3<<endl;
	getch();
	return 0;
}
Вот в этой строке:
istream& operator >> (istream& s, Distance& d)
происходит что?
Как понимаю я:
по ссылке к классу istream создаётся объект s класса istream, создаётся поток извлечения для второго аргумента класса Distance связь с которым тоже по ссылке, для объекта d (для определённого поля).
Когда данные извлечены из клавиатуры в ОП, объект s возвращается по ссылке в main.
Вопрос: куда? к кому?
К cin?
Так ведь s уже по идее извлёк данные в ОП...
KAMLS вне форума Ответить с цитированием
Старый 03.08.2017, 11:03   #2
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Сообщение от KAMLS Посмотреть сообщение
по ссылке к классу istream создаётся объект s класса istream, создаётся поток извлечения для второго аргумента класса Distance связь с которым тоже по ссылке, для объекта d (для определённого поля).
я не смог это распарсить

Просто создали функцию с особым именем "operator >>", возвращающую ссылку на объект istream и принимающую два аргумента: ссылки на объект istream и какой-то ваш объект (по ссылке чтоб не было лишнего копирования).

Когда вы используете >> с значениями подходящих типов компилятор вызовет эту функцию.

(если что, cout и cin это глобальные переменные с типом ostream/istream)

То есть при
Код:
cin >> dist
вы по сути делаете что-то типа
Код:
operator>>(cin, dist)
а при
Код:
cin >> dist1 >> dist2
Код:
operator>>(operator>>(cin, dist1), dist2)
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 03.08.2017 в 11:07.
Alex11223 вне форума Ответить с цитированием
Старый 03.08.2017, 14:17   #3
KAMLS
Форумчанин
 
Регистрация: 09.04.2017
Сообщений: 598
По умолчанию

))
Спасибо.
Вот не знал я, что такое "распарсить". Но по смыслу понял, что это значит, что человек не расшифровал, не понял смысл.
потом глянул в сети и узнал наверняка)) Совпало))
Так вот и по смыслу программы. Я понимаю что там делается. понимаю что на что и как влияет. Но вот почему именно так это записывается, какова логика написания именно так - не понимаю. Это и хотел спросить, этак немного коряво))
Просто зазубрить что и как взаимодействует мне мало. Я хочу понимать суть, корни происходящего.
Вы немного прояснили суть. Спасибо))
Там в теле функции есть
Код:
s>>d.feet;
Вот это s, это ведь объект ifstream? Типа вместо cin?

Последний раз редактировалось KAMLS; 03.08.2017 в 14:20.
KAMLS вне форума Ответить с цитированием
Старый 03.08.2017, 15:16   #4
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Давайте по порядку:
Допустим есть некоторый класс А с каким-то набором методов и вы хотите расширить его функциональность, например, чтобы его func1(int a) могла принимать в качестве параметра ваш тип. Какие у вас варианты?
1. Влезть в класс, изменить его дописав нужную функцию. Но стримовские классы это часть стандартной библиотеки и не очень хорошо так делать. Тем более что вам придется распространять измененную std со своей прогой.
2. Отнаследоваться от А и добавить перегрузку функции. Как-то многовато телодвижений.
3. Что собственно тут и происходит. Создать свободную функцию, первым параметром, естественно, будет класс A, а втором аргументом ваш параметр.
Все работает и вам достаточно только дописать одну функцию.

Ссылка возвращается, чтобы можно было создавать "цепочки".
p51x на форуме Ответить с цитированием
Старый 03.08.2017, 15:58   #5
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Цитата:
Сообщение от KAMLS Посмотреть сообщение
Но вот почему именно так это записывается, какова логика написания именно так - не понимаю
Не обязательно писать так, можно внутри самого класса добавить operator<< с нужным одним параметром. Тогда однако придется писать
YourClassInstance << cin
или
YouClassInstance >> cout
что несколько не интуитивно.

По сути нужно добавить метод в класс cin/cout.
Именно для этого для математических операторов допустима запись operator XXX(lvalue, rvalue) вне декларации класса.
waleri на форуме Ответить с цитированием
Старый 03.08.2017, 16:28   #6
KAMLS
Форумчанин
 
Регистрация: 09.04.2017
Сообщений: 598
По умолчанию

Кое-что проясняется, спасибо. Но вот этот вот вопрос:
Там в теле функции есть
Код:

s>>d.feet;

Вот это s, это ведь объект istream? Типа вместо cin?

Строка 20 и 21

Код:
cout<<"\nВведите футы: ";  s>>d.feet;
	cout<<"\nВведите дюймы: "; s>>d.inches;
KAMLS вне форума Ответить с цитированием
Старый 03.08.2017, 16:30   #7
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Это не вместо, это параметр функции. Передадите туда cin будет из него брать, передадите другой - из другого.
p51x на форуме Ответить с цитированием
Старый 03.08.2017, 17:58   #8
KAMLS
Форумчанин
 
Регистрация: 09.04.2017
Сообщений: 598
По умолчанию

Да, параметр функции operator>>, типа данных "объект класса istream" передаваемого по ссылке в переменную называемую "s" употребляемую внутри этой функции во время действия этой функции.
Но у класса istream много разного функционала, его объекты могут многое. Стало быть символ ">>" указывает что данный объект будет работать на извлечение? Так?
Более того, поскольку этот объект возвращается по ссылке в main, он содержит в себе введённые в функции поля значения класса Distance? Так?
И во время выполнения cin>>dist1>>dist2; он возвращает значения полей объекта dist1 а потом dist2 и записывает данные в поля этих объектов? Или это происходит сразу во время выполнения функции?
А зачем тогда возврат значения по ссылке?
Вот как-то так у меня вопросы роятся)))))
KAMLS вне форума Ответить с цитированием
Старый 03.08.2017, 18:06   #9
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Сообщение от KAMLS Посмотреть сообщение
А зачем тогда возврат значения по ссылке?
чтобы можно было к нему снова применить что-то (без разделения на несколько statement'ов), смотрите мой пример.

Или вопрос был почему не по значению? Чтоб не копировать.

А, и еще в >> аргумент должен быть по ссылке потому что вам ж надо писать туда.
Цитата:
Сообщение от KAMLS Посмотреть сообщение
Или это происходит сразу во время выполнения функции?
там нет магии, что написано, то и происходит.
Смотрите мой пример.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 03.08.2017 в 18:17.
Alex11223 вне форума Ответить с цитированием
Старый 04.08.2017, 06:37   #10
KAMLS
Форумчанин
 
Регистрация: 09.04.2017
Сообщений: 598
По умолчанию

Спасибо.
Там я интересовался, что быть может в поля объекта Distance значения записываются во время выполнения функции? Я так делал когда возвращаемым значением функции бывало void.
Код:
istream& operator >> (istream& s, Distance& d) интересует эта строка
{
	cout<<"\nВведите футы: ";  s>>d.feet;
	cout<<"\nВведите дюймы: "; s>>d.inches;
	return s;
}
Видите, если тут поставить возвращаемое значение void, то получается что значения в поля объекта будут записаны во время выполнения функции. Вот тут то я и поинтересовался, а зачем тогда возвращение по ссылке объекта класса istream, содержащего эти же значения?

Последний раз редактировалось KAMLS; 04.08.2017 в 06:56.
KAMLS вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
перевести программу на с++ т.е printf|scanf на cout |cin очень нужно Faridun Общие вопросы C/C++ 6 18.04.2013 22:54
перевести программу на с++ т.е printf|scanf на cout |cin очень нужно Faridun Visual C++ 0 16.04.2013 14:18
cout., cin., cout.setf, cout.unsetf kineziz Общие вопросы C/C++ 1 06.05.2012 02:50
Разница между cout/cin && printf/scanf treis1000 Общие вопросы C/C++ 7 20.03.2012 18:49