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

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

Восстановить пароль Регистрация
 
Riderik
 Аватар для Riderik
28 / 28 / 1
Регистрация: 24.07.2011
Сообщений: 171
21.01.2012, 20:05     Вопрос о перегрузке ++/-- #1
Рассмотрим простой пример постфиксной и префиксной операции инкремента:
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. То есть смысл постфиксного оператора теряется. Я что-то не так написал или для классов постфиксный и префиксный оператор имеют одинаковый приоритет?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
NoMasters
Псевдослучайный
1737 / 1080 / 69
Регистрация: 13.09.2011
Сообщений: 3,094
21.01.2012, 20:08     Вопрос о перегрузке ++/-- #2
Постфиксный оператор должен был вернуть копию первоначального объекта, код коряв.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
21.01.2012, 20:08     Вопрос о перегрузке ++/-- #3
Вы понимаете что из себя представляет постфиксный оператор?
C++
1
2
3
4
5
Counter operator++(int) {
Counter temp( *this );
count++;
return temp;
}
Riderik
 Аватар для Riderik
28 / 28 / 1
Регистрация: 24.07.2011
Сообщений: 171
21.01.2012, 20:11  [ТС]     Вопрос о перегрузке ++/-- #4
Ясно, спасибо. Просто думал, что приоритетность операций сохраняется и оно все равно должно сначала вывести, а потом увеличить count.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
21.01.2012, 20:16     Вопрос о перегрузке ++/-- #5
Так она сохраняется. Вы же выводите не элемент данных count, а сам объект Counter.
Riderik
 Аватар для Riderik
28 / 28 / 1
Регистрация: 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.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
21.01.2012, 20:29     Вопрос о перегрузке ++/-- #7
Вот именно, в вашем примере вызывается оператор++ для постинкремента, далее вы в нем увеличиваете строкой count++; элемент данных count на единицу, и после чего возвращаете ссылку на уже измененный объект Counter.
Riderik
 Аватар для Riderik
28 / 28 / 1
Регистрация: 24.07.2011
Сообщений: 171
21.01.2012, 20:31  [ТС]     Вопрос о перегрузке ++/-- #8
Toshkarik, рассматриваем ваш вариант реализации постинкремента
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
21.01.2012, 20:37     Вопрос о перегрузке ++/-- #9
Цитата Сообщение от Riderik Посмотреть сообщение
думал, что приоритетность операций сохраняется и оно все равно должно сначала вывести, а потом увеличить count
Каким образом? В 7 строке после ++count стоит точка с запятой. Это точка следования. После неё выражение завершается. Теперь не важно, написали вы ++count или count++, после точки следование значение увеличивается.

Цитата Сообщение от Riderik Посмотреть сообщение
(i++)++;
Это, конечно, ваш класс, и с ним вы вольны делать что угодно, но негласно считается, что перегруженный оператор должен полностью логически соответствовать своему аналогу для элементарных типов (если случай не особый), а для элементарных типов такая запись будет считаться ошибочной. Потому что для элементарных типов только преинкремент/предекремент возвращает ссылку, а постинкремент/постдекремент - значение.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 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;
    }
Riderik
 Аватар для Riderik
28 / 28 / 1
Регистрация: 24.07.2011
Сообщений: 171
21.01.2012, 20:43  [ТС]     Вопрос о перегрузке ++/-- #11
Toshkarik, ну я так и подумал, спасибо.

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

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

Добавлено через 1 минуту
или в реализации оператора постинкремента для стандартного типа так же возвращается значение "до"?
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
21.01.2012, 20:52     Вопрос о перегрузке ++/-- #14
Именно, это и написал silent_1991. При постинрекементе\постдекременте встроенных типов возвращается значение "до". Понимаете i++ в данном случае это не объект i, а вызываемая функция для этого объекта, i.operator++( 0 );, которая возвращает значение.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
21.01.2012, 20:54     Вопрос о перегрузке ++/-- #15
Riderik, нет, не выше. Суть операции постинкремента не в том, что он выполняется последним, а в том, что он возвращает значение до увеличения.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.01.2012, 20:57     Вопрос о перегрузке ++/--
Еще ссылки по теме:

О перегрузке операторов C++
C++ Ошибка в перегрузке
C++ Ошибка в перегрузке операторов?

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

Или воспользуйтесь поиском по форуму:
Riderik
 Аватар для Riderik
28 / 28 / 1
Регистрация: 24.07.2011
Сообщений: 171
21.01.2012, 20:57  [ТС]     Вопрос о перегрузке ++/-- #16
ну ясно. Еще раз спасибо. Всегда думал, что тут всё дело в приоритетности.
Yandex
Объявления
21.01.2012, 20:57     Вопрос о перегрузке ++/--
Ответ Создать тему
Опции темы

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