Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
No10
30 / 28 / 2
Регистрация: 03.06.2010
Сообщений: 465
#1

Проблемы с понимаем перезагрузки операторов - C++

22.05.2012, 15:55. Просмотров 1030. Ответов 5
Метки нет (Все метки)

ни как не могу понять синтаксис перезагрузки операций. Просто жесть. Вот пример кодаЖ

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <iomanip>
#include <windows.h>
#include <math.h>
 
using namespace std;
 
char bufRus[256];
char* Rus(const char* text) {
      CharToOem(text, bufRus);
      return bufRus;
      }
 
class PhoneNumber{
        friend ostream &operator<< (ostream &, const PhoneNumber &);
        friend istream &operator>> (istream &, PhoneNumber &);
    private:
        char areaCode[4];
        char exchange[4];
        char line[5];
};
 
ostream &operator<< (ostream &output, const PhoneNumber &num)
{
    output << "(" << num.areaCode << ") " << num.exchange << "-" << num.line;
    return output;
}
 
istream &operator>> (istream &input, PhoneNumber &num)
{
    input.ignore();
    input.getline(num.areaCode, 4);
    input.ignore(2);
    input.getline(num.exchange, 4);
    input.ignore();
    input.getline(num.line, 5);
 
    return input;
}
 
int main()
{
    PhoneNumber phone;
    cout << Rus("Введите номер телефона в виде (123) 456-7890:") << endl;
    cin >> phone;
    cout << Rus("Был введён номер телефона ") << phone << endl;
    system("pause");
    return 0;
}
Почему мы не пишем тип возвращаемых данных в обьявлении дружественной функции:
friend ostream &operator<< (ostream &, const PhoneNumber &);
Почему мы не пишем void, ведь она ничего не возвращает.
friend void ostream &operator<< (ostream &, const PhoneNumber &);
А вот это из разряда самого не понятного доя меня:
friend ostream &operator<< (ostream &, const PhoneNumber &);
Где родился тип ostream? зачем мы получаем на него ссылку.... Я предпологаю что это ссылка на функцию friend ostream &operator<<, но я очень плохо соображаю в ссылках на функцию и что это даёт... Почему когда я использую оператор << для обычного текста(cout << Rus("Введите номер телефона в виде (123) 456-7890:") ) у меня не срабатывает функция friend ostream &operator<<? Она вроде и не нужна там, но почему? Очень всё запутано, кто может пожалуйста обьясните, буду ооочень благодарен!!!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.05.2012, 15:55     Проблемы с понимаем перезагрузки операторов
Посмотрите здесь:

C++ Переопределение операторов
Перегрузка операторов C++
Перегрузка операторов C++
Модификация перезагрузки C++
Перегрузка операторов C++
Перекрытие операторов C++
C++ Проблемы с перегрузкой операторов файлового вводы/вывода
Перегрузка операторов C++
C++ Перегрузка операторов
Перегрузка операторов 2 C++
Перегрузка операторов C++
C++ Задача с использованием логических операторов и операторов ветвления

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DU
1480 / 1056 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
22.05.2012, 16:02     Проблемы с понимаем перезагрузки операторов #2
friend ostream &operator<< (ostream &, const PhoneNumber &);
ostream & перед operator<<... это как раз и есть возвращаемый тип. т.е. эта дружественная функция, которая должна вернуть ссылку на ostream.

friend ostream &operator<< (ostream &, const PhoneNumber &);
это функция, которая возвращает ссылку на ostream, а в качестве аргументов принимает ссылку на ostream и константную ссылку на PhoneNumber.
чтобы вызвать эту функцию ей нужно передать эти аргументы. ну а так как это оператор, то синтаксис вызова немного отличается от синтаксиса вызова обычных функций.
запись
std::cout << PhoneNumber();
это вызов такой функции, которой передается std::cout (std::ostream&), и PhoneNumber() (по константной ссылке)
Чтобы увидеть что, она что-то возвращает, можно написать так:
std::ostream& out = std::cout << PhoneNumber();
No10
30 / 28 / 2
Регистрация: 03.06.2010
Сообщений: 465
22.05.2012, 18:40  [ТС]     Проблемы с понимаем перезагрузки операторов #3
Спасибо! ostream что это за тип? я его не создавал следовательно он не пользовательский, чей он? И зачем нужен? можешьпожалуйста обьяснить схему работы всех этих операторов? что именно происходит при вызове <<?
silent_1991
Эксперт С++
4952 / 3028 / 149
Регистрация: 11.11.2009
Сообщений: 7,026
Завершенные тесты: 1
24.05.2012, 12:15     Проблемы с понимаем перезагрузки операторов #4
No10, раз вы его не создавали, но он есть, то можно было бы догадаться, что он библиотечный. Это базовый класс для всех потоков вывода.
Ваша проблема в том, что вы воспринимаете перегруженные операторы как нечто совершенно обособленное от всего остального. На самом деле это совершенно обычные функции с несколько необычным именем. И подчиняются тем же правилам, что и остальные функции. Единственное исключение - они должны принимать количество аргументов, равное количеству операндов оператора (при перегрузке в виде глобальной функции) или на единицу меньшее (при перегрузке в виде метода класса). Ну и хотя бы один из аргументов должен быть объектом какого-либо класса (т.е. нельзя перегрузить оператор сложения для двух интов).
Из вашего оператора << теоретически можно было бы возвращать и void, но тогда нельзя было бы написать так:
C++
1
std::cout << my_obj1 << my_obj2;
поскольку в результате выполнения первого вывода (т.е. применения оператора << к объектам std::cout и my_obj1) не остаётся объекта, который можно было бы передать в operator<< в качестве первого аргумента. Потому мы и возвращаем из него ссылку на поток, который был ему передан при вызове. Фактически указанный выше вывод выполняется в несколько этапов:
1. Вызывается operator<<, принимающий std::cout и my_obj1
2. В результате этого вызова возвращается ссылка на поток, который был передан при вызове - на std::cout
3. Полученная ссылка снова передаётся во второй вызов operator<< в качестве первого аргумента, а my_obj2 - в качестве второго.
Вот так каскадно и вызывается оператор << для каждого вывода.
Если углубиться, то можно сказать, что компилятор при применении перегруженного оператора заменяет его вызов на явный вызов функции (метода). Т.е. если вы пишете my_obj1 + my_obj2, при этом перегрузив оператор +, принимающий в качестве аргументов объекты соответствующего класса, то компилятор подобный вызов заменит на operator+(my_obj1, my_obj2);
Suares
0 / 0 / 0
Регистрация: 28.02.2013
Сообщений: 106
03.04.2013, 22:29     Проблемы с понимаем перезагрузки операторов #5
Дошел я в книге Дейтела до перегрузки операций и там был такой же код. Переписав его, я получил что при вводе
"(ххх) ххх-хххх", программа выводит только "(ххх) -". Как я понял у меня с 34 по 36 строчку ничего не выпоняется! Подскажите как исправить
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.04.2013, 02:38     Проблемы с понимаем перезагрузки операторов #6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
istream &operator>> (istream &input, PhoneNumber &num)
{
    input.ignore();
    input.getline(num.areaCode, 4);
    input.clear();
    input.ignore(2);
    input.getline(num.exchange, 4);
    input.clear();
    input.ignore();
    input.getline(num.line, 5);
    input.clear();
 
    return input;
}
Добавлено через 2 минуты
Или использовать istream& get (char* s, streamsize n);:
C++
1
2
3
4
5
6
7
8
9
10
11
istream &operator>> (istream &input, PhoneNumber &num)
{
    input.ignore();
    input.get(num.areaCode, 4);
    input.ignore(2);
    input.get(num.exchange, 4);
    input.ignore();
    input.get(num.line, 5);
    
    return input;
}
Yandex
Объявления
04.04.2013, 02:38     Проблемы с понимаем перезагрузки операторов
Ответ Создать тему
Опции темы

Текущее время: 10:53. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru