Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
Riderik
28 / 28 / 4
Регистрация: 24.07.2011
Сообщений: 171
1

Вопрос о перегрузке ++/--

21.01.2012, 20:05. Просмотров 855. Ответов 15
Метки нет (Все метки)

Рассмотрим простой пример постфиксной и префиксной операции инкремента:
C++
1
2
3
4
5
6
7
8
int main()
{
    int i=0;
    cout<< i++;
    cout<< ++i;
    _getch();
    return 0;
}
На экран выведется ,как тому и положено, 02, так как при cout<< i++; приоритет имеет вывод.
Теперь тот же пример но для класса Counter:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Counter
{
    int count;
public:
    Counter(int a): count(a){}
    ~Counter(){}
    Counter& operator++(){ ++count; return *this;}
    Counter& operator++(int) { count++; return *this;}
    friend ostream& operator<<(ostream &out, Counter &A) {out<<A.count; return out;} 
};
 
int main()
{
    Counter i=0;
    cout<< i++;
    cout<< ++i;
    _getch();
    return 0;
}
Выведет 12. То есть смысл постфиксного оператора теряется. Я что-то не так написал или для классов постфиксный и префиксный оператор имеют одинаковый приоритет?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.01.2012, 20:05
Ответы с готовыми решениями:

Теоретический вопрос о перегрузке функций
Доброго времени суток! Помогите, пожалуйста, вот с такой проблемой. ...

Уточняющий вопрос: почему при перегрузке оператора [] необходимо возвращать ссылку?
Сабж. Ну, то есть есть класс, что-то такое: #include &lt;iostream&gt; using...

О перегрузке операторов
Вот у меня есть код программы : #include &quot;stdafx.h&quot; #include &lt;iostream&gt;...

Ошибка в перегрузке
Заголовок #ifndef CHALLENGE_H #define CHALLENGE_H #include &lt;ostream&gt;...

Ошибки в перегрузке << и >>
Привет, я делаю упражнение, но у меня не выходит считывать информацию с файла....

15
NoMasters
Псевдослучайный
1909 / 1120 / 90
Регистрация: 13.09.2011
Сообщений: 3,178
21.01.2012, 20:08 2
Постфиксный оператор должен был вернуть копию первоначального объекта, код коряв.
1
Toshkarik
1149 / 866 / 90
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
21.01.2012, 20:08 3
Вы понимаете что из себя представляет постфиксный оператор?
C++
1
2
3
4
5
Counter operator++(int) {
Counter temp( *this );
count++;
return temp;
}
1
Riderik
28 / 28 / 4
Регистрация: 24.07.2011
Сообщений: 171
21.01.2012, 20:11  [ТС] 4
Ясно, спасибо. Просто думал, что приоритетность операций сохраняется и оно все равно должно сначала вывести, а потом увеличить count.
0
Toshkarik
1149 / 866 / 90
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
21.01.2012, 20:16 5
Так она сохраняется. Вы же выводите не элемент данных count, а сам объект Counter.
0
Riderik
28 / 28 / 4
Регистрация: 24.07.2011
Сообщений: 171
21.01.2012, 20:28  [ТС] 6
Toshkarik, ну так ведь и оператор++ вызывается относительно объекта Counter, а не относительно данной count

Добавлено через 9 минут
Кстати, вот получается, что в постфиксном операторе возвращается копия.. А если результат этого оператора еще изменить, то изменится копия, а исходный объект, относительно которого и вызывался оператор, останется неизменным. Я не знаю, зачем потребуется изменять этот результат, но мало ли. Хотя для стандартных типов, при попытки изменения выбивает ошибку. Но для классов работает.
C++
1
2
3
Count i=0;
(i++)++;
cout<<i;
Выведет 1.
0
Toshkarik
1149 / 866 / 90
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
21.01.2012, 20:29 7
Вот именно, в вашем примере вызывается оператор++ для постинкремента, далее вы в нем увеличиваете строкой count++; элемент данных count на единицу, и после чего возвращаете ссылку на уже измененный объект Counter.
0
Riderik
28 / 28 / 4
Регистрация: 24.07.2011
Сообщений: 171
21.01.2012, 20:31  [ТС] 8
Toshkarik, рассматриваем ваш вариант реализации постинкремента
0
silent_1991
Эксперт С++
5009 / 3069 / 270
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
21.01.2012, 20:37 9
Цитата Сообщение от Riderik Посмотреть сообщение
думал, что приоритетность операций сохраняется и оно все равно должно сначала вывести, а потом увеличить count
Каким образом? В 7 строке после ++count стоит точка с запятой. Это точка следования. После неё выражение завершается. Теперь не важно, написали вы ++count или count++, после точки следование значение увеличивается.

Цитата Сообщение от Riderik Посмотреть сообщение
(i++)++;
Это, конечно, ваш класс, и с ним вы вольны делать что угодно, но негласно считается, что перегруженный оператор должен полностью логически соответствовать своему аналогу для элементарных типов (если случай не особый), а для элементарных типов такая запись будет считаться ошибочной. Потому что для элементарных типов только преинкремент/предекремент возвращает ссылку, а постинкремент/постдекремент - значение.
0
Toshkarik
1149 / 866 / 90
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
21.01.2012, 20:40 10
И что бы избежать ошибочных записей ( i++ )++; нужно возвращать константный объект.
C++
1
2
3
4
5
6
    const Counter operator++( int ) {
    Counter temp = *this;
    count++;
 
    return temp;
    }
0
Riderik
28 / 28 / 4
Регистрация: 24.07.2011
Сообщений: 171
21.01.2012, 20:43  [ТС] 11
Toshkarik, ну я так и подумал, спасибо.

silent_1991, да, да это ясно. Я о другом уже. вызов идет относительно объекта типа Counter, а не int count. То есть при записи cout<<i++; по идее, сначала должен сработать оператор <<, и только после него вызов оператора ++. А это значит, что если приоритетность оставалась бы прежней, то не имеет значение реализация постинкремента. Сначала вызвался бы operator<<(ostream, Counter), а за ним Counter::operator++(). Но так не происходит. Почему?
0
Toshkarik
1149 / 866 / 90
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
21.01.2012, 20:45 12
С чего вы взяли что сначала вызывается оператор <<?

Ой извиняюсь, << вроде не оператор, а операция передачи в поток.
0
Riderik
28 / 28 / 4
Регистрация: 24.07.2011
Сообщений: 171
21.01.2012, 20:48  [ТС] 13
Toshkarik, у него приоритет выше. Разве нет?

Добавлено через 1 минуту
или в реализации оператора постинкремента для стандартного типа так же возвращается значение "до"?
0
Toshkarik
1149 / 866 / 90
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
21.01.2012, 20:52 14
Именно, это и написал silent_1991. При постинрекементе\постдекременте встроенных типов возвращается значение "до". Понимаете i++ в данном случае это не объект i, а вызываемая функция для этого объекта, i.operator++( 0 );, которая возвращает значение.
0
silent_1991
Эксперт С++
5009 / 3069 / 270
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
21.01.2012, 20:54 15
Riderik, нет, не выше. Суть операции постинкремента не в том, что он выполняется последним, а в том, что он возвращает значение до увеличения.
1
Riderik
28 / 28 / 4
Регистрация: 24.07.2011
Сообщений: 171
21.01.2012, 20:57  [ТС] 16
ну ясно. Еще раз спасибо. Всегда думал, что тут всё дело в приоритетности.
0
21.01.2012, 20:57
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.01.2012, 20:57

Ошибка в перегрузке оператора +=
В строках 42-50 пытаюсь описать перегрузку операции +=, но выдаёт ошибку...

Ошибка в перегрузке операторов?
не могу понять в чем ошибка class cMatrix { private: int rows; int...

Указатель в перегрузке оператора
Не понимаю, зачем здесь указатель на оператор и на параметр функции? ostream...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru