Пространства имён
Варианты
Действия

Операторы инкремента/декремента

Материал из cppreference.com
< cpp‎ | language
 
 
Язык С++
Общие темы
Управление потоком
Операторы условного выполнения
Операторы итерации (циклы)
Операторы перехода
Функции
Объявление функции
Выражение лямбда-функции
Спецификатор inline
Спецификации динамических исключений(до C++17*)
Спецификатор noexcept(C++11)
Исключения
Пространства имён
Типы
Спецификаторы
decltype(C++11)
auto(C++11)
alignas(C++11)
Спецификаторы длительности хранения
Инициализация
Выражения
Альтернативные представления
Литералы
Логические - Целочисленные - С плавающей запятой
Символьные - Строковые - nullptr(C++11)
Определяемые пользователем(C++11)
Утилиты
Атрибуты(C++11)
Types
Объявление typedef
Объявление псевдонима типа(C++11)
Casts
Неявные преобразования - Явные преобразования
static_cast - dynamic_cast
const_cast - reinterpret_cast
Выделение памяти
Классы
Свойства функции класса
Специальные функции-элементы
Шаблоны
Разное
 

Операторы инкремента /декремента инкрементируют или декрементируют значение объекта.

Имя оператора Синтаксис Пере​гружа​емый Примеры прототипов (для 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);
Примечание
  • Префиксные версии встроенных операторов возвращают ссылки, а постфиксные версии возвращают значения, и обычно пользовательские перегрузки следуют шаблону, так что пользовательские операторы могут использоваться так же, как и встроенные. Однако при перегрузке определяемого пользователем оператора в качестве возвращаемого типа может использоваться любой тип (включая void).
  • Параметр int это фиктивный параметр, используемый для различения префиксной и постфиксной версий операторов. Когда вызывается пользовательский постфиксный оператор, значение, переданное в этом параметре, всегда равно нулю, хотя оно может быть изменено путём вызова оператора с использованием нотации вызова функции (например, a.operator++(2) или operator++(a, 2)).

Содержание

[править]Объяснение

Операторы префиксного инкремента и префиксного декремента инкрементируют или декрементируют значение объекта и возвращают ссылку на результат.

Постфиксный инкремент и постфиксный декремент создают копию объекта, инкрементируют или декрементируют значение объекта и возвращают копию до инкремента или декремента.

Использование в качестве операнда встроенной версии этих операторов lvalue неклассового типа, квалифицированного как volatile, является устаревшим.

(начиная с C++20)

[править]Встроенные префиксные операторы

Выражения префиксного инкремента и декремента имеют форму

++expr
--expr
1) префиксный инкремент (пре-инкремент)
2) префиксный декремент (пре-декремент)

Операнд 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--
1) постфиксный инкремент (пост-инкремент)
2) постфиксный декремент (пост-декремент)

Операнд 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 += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>= b

++a
--a
a++
a--

+a
-a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

!a
a && b
a || b

a == b
a != b
a < b
a > b
a <= b
a >= b
a <=> b

a[...]
*a
&a
a->b
a.b
a->*b
a.*b

вызов функции
a(...)
запятая
a, b
условный
a ? b : c
Специальные операторы

static_cast приводит один тип к другому совместимому типу
dynamic_cast приводит к типу в иерархиях наследования
const_cast добавляет или удаляет cv квалификаторы
reinterpret_cast приводит тип к несовместимому типу
приведение в стиле C приводит один тип к другому с помощью сочетания static_cast, const_cast и reinterpret_cast
new создаёт объекты с динамическим классом памяти
delete разрушает объекты, ранее созданные выражением new, и освобождает полученную область памяти
sizeof запрашивает размер типа
sizeof... запрашивает размер пакета параметров(начиная с C++11)
typeid запрашивает сведения о типе
noexcept проверяет, может ли выражение вызвать исключение (начиная с C++11)
alignof запрашивает требования к выравниванию типа (начиная с C++11)

Документация C по Операторы инкремента/декремента
close