自增/自减运算符

来自cppreference.com
< cpp‎ | language
 
 
 
表达式
概述
值类别(左值 lvalue、右值 rvalue、亡值 xvalue)
求值顺序(序列点)
常量表达式
不求值表达式
初等表达式
lambda 表达式(C++11)
字面量
整数字面量
浮点字面量
布尔字面量
字符字面量,包含转义序列
字符串字面量
空指针字面量(C++11)
用户定义字面量(C++11)
运算符
赋值运算符a=ba+=ba-=ba*=ba/=ba%=ba&=ba|=ba^=ba<<=ba>>=b
自增与自减++a--aa++a--
算术运算符+a-aa+ba-ba*ba/ba%b~aa&ba|ba^ba<<ba>>b
逻辑运算符a||ba&&b!a
比较运算符a==ba!=ba<ba>ba<=ba>=b
成员访问运算符a[b]*a&aa->ba.ba->*ba.*b
其他运算符a(...)a,ba?b:c
运算符的替代表示形式
优先级和结合性
折叠表达式(C++17)
new 表达式
delete 表达式
throw 表达式
alignof
sizeof
sizeof...(C++11)
typeid
noexcept(C++11)
运算符重载
类型转换
隐式转换
const_cast
static_cast
reinterpret_cast
dynamic_cast
显式转换 (T)aT(a)
用户定义转换
 

自增/自减运算符使对象的值进行递增或递减。

运算符名 语法 可重载 原型实例(对于 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))。

目录

[编辑] 解释

前置自增前置自减运算符使对象的值递增或递减,并返回指代其结果的引用。

后置自增后置自减创建对象的一个副本,使对象的值递增或递减,然后返回其进行递增或递减前的副本。

[编辑] 内建的前置运算符

对于每个除 bool 以外的可选地带有 volatile 限定的算术类型 A,以及每个指向可选地带有 cv 限定的对象类型的可选地带有 volatile 限定的指针类型 P,有如下函数签名参与重载解析:

A& operator++(A&)
bool& operator++(bool&)
(过时)(C++17 前)
P& operator++(P&)
A& operator--(A&)
P& operator--(P&)

内建的前置自增和自减运算符的操作数,必须是非布尔算术类型或者完整的对象类型的指针类型的可改动的(非 const)左值。对于非布尔操作数,表达式 ++x 严格等价于 x += 1,而表达式 --x 严格等价于 x -= 1,就是说,前置自增或自减就是标识了被改动的操作数的左值表达式。为算术运算符所定义的所有的算术转换规则和指针算术规则都适用于此。

如果前置自增运算符的操作数具有 bool 类型,则它被设置为 true (过时) (C++17 前)

[编辑] 内建的后置运算符

对于每个除 bool 以外的可选地带有 volatile 限定的算术类型 A,以及每个指向可选地带有 cv 限定的对象类型的可选地带有 volatile 限定的指针类型 P,有如下函数签名参与重载解析:

A operator++(A&, int)
bool operator++(bool&, int)
(过时)(C++17 前)
P operator++(P&, int)
A operator--(A&, int)
P operator--(P&, int)

内建的后置自增或自减运算符的操作数,必须是非布尔算术类型或者完整的对象类型的指针类型的可改动的(非 const)左值。其结果为操作数的原值的纯右值副本。其副作用,对于非布尔操作数,表达式 x++ 如同以 x += 1 的求值来改动其操作数的值,而表达式 x-- 如同以 x -= 1 的求值来改动其操作数的值。为算术运算符所定义的所有的算术转换规则和指针算术规则都适用于此。

如果后置自增运算符的操作数具有 bool 类型,则它被设置为 true (过时) (C++17 前)

[编辑] 示例

#include <iostream>
int main()
{
    int n = 1;
    int n2 = ++n;
    int n3 = ++ ++n;
    int n4 = n++;
//  int n5 = n1++ ++;   // 错误
//  int n6 = n1 + ++n1; // 未定义行为
    std::cout << "n = " << n << '\n'
              << "n2 = " << n2 << '\n'
              << "n3 = " << n3 << '\n'
              << "n4 = " << n4 << '\n';
}

输出:

n = 5
n2 = 2
n3 = 4
n4 = 4

[编辑] 注解

由于涉及了副作用,使用内建的自增和自减运算符时必须小心,避免由于违反顺序性规则而导致的未定义行为。

由于后置自增和后置自减会产生对象的临时副本,所以在并不使用其返回值的语境下,通常前置自增前置自减运算符要更加高效一些。

[编辑] 标准库

需对标准库类型都重载了自增和自减运算符。尤其是,每个 Iterator 都重载了 operator++,而且每个 BidirectionalIterator 都重载了 operator--,即便某些特定的迭代器的运算符是空操作。

对算术类型的重载
使原子值自增或自减一
(std::atomic 的公开成员函数) [编辑]
递增或递减滴答计数
(std::chrono::duration 的公开成员函数) [编辑]
对迭代器类型的重载
推进迭代器
(std::raw_storage_iterator 的公开成员函数) [编辑]
推进或回退迭代器
(std::reverse_iterator 的公开成员函数) [编辑]
推进或回退迭代器
(std::move_iterator 的公开成员函数) [编辑]
空操作
(std::front_insert_iterator 的公开成员函数) [编辑]
空操作
(std::back_insert_iterator 的公开成员函数) [编辑]
空操作
(std::insert_iterator 的公开成员函数) [编辑]
推进迭代器
(std::istream_iterator 的公开成员函数) [编辑]
空操作
(std::ostream_iterator 的公开成员函数) [编辑]
推进迭代器
(std::istreambuf_iterator 的公开成员函数) [编辑]
空操作
(std::ostreambuf_iterator 的公开成员函数) [编辑]
推进迭代器到下一个匹配
(std::regex_iterator 的公开成员函数) [编辑]
推进迭代器到下一个子匹配
(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->b
a.b
a->*b
a.*b

a(...)
a, b
? :

特殊运算符

static_cast 转换一个类型为另一相关类型
dynamic_cast 在继承层级中转换
const_cast 添加或移除 cv 限定符
reinterpret_cast 转换类型到无关类型
C 风格转型static_castconst_castreinterpret_cast 的混合转换一个类型到另一类型
new 创建有动态存储期的对象
delete 销毁先前由 new 表达式创建的对象,并释放其所拥有的内存区域
sizeof 查询类型的大小
sizeof... 查询形参包的大小(C++11 起)
typeid 查询类型的类型信息
noexcept 查询表达式是否能抛出异常(C++11 起)
alignof 查询类型的对齐要求(C++11 起)