Операторы инкремента/декремента
Операторы инкремента /декремента инкрементируют или декрементируют значение объекта.
Имя оператора | Синтаксис | Перегружаемый | Примеры прототипов (для class T) | |
---|---|---|---|---|
Определение внутри класса | Определение вне класса | |||
префиксный икремент | ++a | Да | T& T::operator++(); | T& operator++(T& a); |
префиксный декремент | --a | Да | T& T::operator--(); | T& operator--(T& a); |
постфиксный инкремент | a++ | Да | T T::operator++(int); | T operator++(T& a, int); |
постфиксный декремент | a-- | Да | T T::operator--(int); | T operator--(T& a, int); |
|
Содержание |
[править]Объяснение
Операторы префиксного инкремента и префиксного декремента инкрементируют или декрементируют значение объекта и возвращают ссылку на результат.
Постфиксный инкремент и постфиксный декремент создают копию объекта, инкрементируют или декрементируют значение объекта и возвращают копию до инкремента или декремента.
Использование в качестве операнда встроенной версии этих операторов lvalue неклассового типа, квалифицированного как volatile, является устаревшим. | (начиная с C++20) |
[править]Встроенные префиксные операторы
Выражения префиксного инкремента и декремента имеют форму
++ expr | |||||||||
-- expr | |||||||||
Операнд expr встроенного префиксного оператора инкремента или декремента должен быть изменяемым (неконстантным) lvalueне логического(начиная с C++17) арифметического типа или указателем на полностью определённый объектный тип. Выражение ++x в точности эквивалентно x +=1 для небулевых операндов(до C++17), а выражение --x в точности эквивалентно x -=1, то есть префиксные инкремент или декремент являетются выражением lvalue, которое идентифицирует изменённый операнд. Все правила арифметического преобразования и правила арифметики указателей, определённые для арифметических операторов, применяются и определяют неявное преобразование (если есть), применяемое к операнду, а также тип возвращаемого выражения.
Если операнд оператора префиксного инкремента имеет тип bool, он устанавливается в true(устарело).(до C++17)
В разрешении перегрузки для пользовательских операторов, для каждого арифметического типа A
, который может быть volatile-квалифицирован, кроме bool, и для каждого необязательно volatile-квалифицированного указателя P
на необязательно cv-квалифицированный тип объекта, следующие сигнатуры функций участвуют в разрешении перегрузки:
A& operator++(A&) | ||
bool& operator++(bool&) | (устарело)(до C++17) | |
P& operator++(P&) | ||
A& operator--(A&) | ||
P& operator--(P&) | ||
[править]Встроенные постфиксные операторы
Выражения постфиксного инкремента и декремента имеют форму
expr++ | |||||||||
expr-- | |||||||||
Операнд expr встроенного постфиксного оператора инкремента или декремента должен быть изменяемым (неконстантным) lvalueнебулевым(начиная с C++17) арифметическим типом или указателем на полностью определённый объектный тип. В результате получается prvalue копия исходного значения операнда. В качестве побочного эффекта выражение x++ изменяет значение своего операнда, как если бы оно вычисляло x +=1 для небулевых операндов(до C++17), а выражение x-- изменяет значение своего операнда, как если бы оно вычисляло x -=1. Все правила арифметического преобразования и правила арифметики указателей, определённые для арифметических операторов применяются и определяют неявное преобразование (если есть), применяемое к операнду, а также тип возвращаемого выражения.
Если операнд оператора постинкремента имеет тип bool, он устанавливается в true(устарело).(до C++17)
В разрешении перегрузки для пользовательских операторов, для каждого арифметического типа A
, который может быть volatile-квалифицированным, кроме bool, и для каждого необязательно volatile-квалифицированного указателя P
на необязательно cv-квалифицированный объектный тип, следующие сигнатуры функций участвуют в разрешении перегрузки:
A operator++(A&, int) | ||
bool operator++(bool&, int) | (устарело)(до C++17) | |
P operator++(P&, int) | ||
A operator--(A&, int) | ||
P operator--(P&, int) | ||
[править]Пример
#include <iostream> int main(){int n1 =1;int n2 =++n1;int n3 =++++n1;int n4 = n1++;// int n5 = n1++ ++; // ошибка// int n6 = n1 + ++n1; // неопределённое поведениеstd::cout<<"n1 = "<< n1 <<'\n'<<"n2 = "<< n2 <<'\n'<<"n3 = "<< n3 <<'\n'<<"n4 = "<< n4 <<'\n';}
Вывод:
n1 = 5 n2 = 2 n3 = 4 n4 = 4
[править]Примечание
Из-за побочных эффектов встроенные операторы инкремента и декремента необходимо использовать с осторожностью, чтобы избежать неопределённого поведения из-за нарушений правил последовательности.
Поскольку во время пост-инкремента и пост-декремента создаётся временная копия объекта, операторы пре-инкремента или пре-декремента обычно более эффективны в контекстах, где возвращаемое значение не используется.
[править]Стандартные библиотеки
Операторы инкремента и декремента перегружены для многих стандартных типов библиотек. В частности, каждый LegacyIterator перегружает operator++, а каждый LegacyBidirectionalIterator перегружает operator--, даже если эти операторы не выполняются для конкретного итератора.
перегрузки для арифметических типов | |
увеличивает или уменьшает атомарное значение на единицу (public функция-элемент std::atomic ) | |
увеличивает или уменьшает количество тактов (public функция-элемент std::chrono::duration<Rep,Period> ) | |
перегрузки для типов итераторов | |
продвигает итератор (public функция-элемент std::raw_storage_iterator ) | |
увеличивает или уменьшает итератор (public функция-элемент std::reverse_iterator ) | |
увеличивает или уменьшает итератор (public функция-элемент std::move_iterator ) | |
нет операции (public функция-элемент std::front_insert_iterator ) | |
нет операции (public функция-элемент std::back_insert_iterator ) | |
нет операции (public функция-элемент std::insert_iterator ) | |
продвигает итератор (public функция-элемент std::istream_iterator ) | |
нет операции (public функция-элемент std::ostream_iterator ) | |
продвигает итератор (public функция-элемент std::istreambuf_iterator ) | |
нет операции (public функция-элемент std::ostreambuf_iterator ) | |
продвигает итератор к следующему совпадению (public функция-элемент std::regex_iterator ) | |
продвигает итератор к следующему подсовпадению (public функция-элемент std::regex_token_iterator ) |
[править]Смотрите также
Общие операторы | ||||||
---|---|---|---|---|---|---|
присваивание | инкремент декремент | арифметические | логические | сравнения | доступ к элементу | другие |
a = b | ++a | +a | !a | a == b | a[...] | вызов функции |
a(...) | ||||||
запятая | ||||||
a, b | ||||||
условный | ||||||
a ? b : c | ||||||
Специальные операторы | ||||||
static_cast приводит один тип к другому совместимому типу |
Документация C по Операторы инкремента/декремента |