C++ 参考手册
- C++11
- C++14
- C++17
- C++20
- C++ 编译器支持情况表
- 独立与宿主实现
- C++ 语言
- 变量模板(C++14 起)
- 整数字面量
- 聚合初始化
- 比较运算符
- 默认比较(C++20 起)
- 转义序列
- for 循环
- while 循环
- 用户定义转换
- SFINAE
- 主函数
- ASCII 码表
- 标识符
- 类型
- 内存模型
- 对象
- 基本概念
- 表达式
- 声明
- 初始化
- 函数
- 语句
- 类
- 运算符重载
- 模板
- 异常
- 事务性内存
- 占位符类型说明符 (C++11 起)
- decltype 说明符
- 函数声明
- final 说明符 (C++11 起)
- override 说明符(C++11 起)
- 引用声明
- 移动构造函数
- 移动赋值运算符
- 枚举声明
- constexpr 说明符(C++11 起)
- 列表初始化 (C++11 起)
- 构造函数与成员初始化器列表
- using 声明
- nullptr,指针字面量
- 基础类型
- 类型别名,别名模版 (C++11 起)
- 形参包
- 联合体声明
- 字符串字面量
- 用户定义字面量 (C++11 起)
- 属性说明符序列(C++11 起)
- Lambda 表达式 (C++11 起)
- noexcept 说明符 (C++11 起)
- noexcept 运算符 (C++11 起)
- alignof 运算符(C++11 起)
- alignas 说明符 (C++11 起)
- 存储类说明符
- 基于范围的 for 循环 (C++11 起)
- static_assert 声明
- 隐式转换
- 代用运算符表示
- 自增/自减运算符
- 折叠表达式(C++17 起)
- 类模板实参推导(C++17 起)
- 模板形参与模板实参
- if 语句
- inline 说明符
- 结构化绑定声明 (C++17 起)
- switch 语句
- 字符字面量
- 命名空间
- 求值顺序
- 复制消除
- consteval 说明符 (C++20 起)
- constinit 说明符 (C++20 起)
- 协程 (C++20)
- 模块 (C++20 起)
- 约束与概念 (C++20 起)
- new 表达式
- do-while 循环
- continue 语句
- break 语句
- goto 语句
- return 语句
- 动态异常说明
- throw 表达式
- try 块
- 命名空间别名
- 类声明
- cv(const 与 volatile)类型限定符
- 默认初始化
- 值初始化(C++03 起)
- 零初始化
- 复制初始化
- 直接初始化
- 常量初始化
- 引用初始化
- 值类别
- C++ 运算符优先级
- 布尔字面量
- 浮点字面量
- typedef 说明符
- 显式类型转换
- static_cast 转换
- dynamic_cast 转换
- const_cast 转换
- reinterpret_cast 转换
- delete 表达式
- 构造函数与成员初始化器列表
- this 指针
- 访问说明符
- 友元声明
- virtual 函数说明符
- explicit 说明符
- 静态成员
- 默认构造函数
- 复制构造函数
- 复制赋值运算符
- 析构函数
- 类模板
- 函数模板
- 显式(全)模板特化
- 汇编声明
- C++ 的历史
- 作用域
- 生存期
- 定义与单一定义规则(ODR)
- 名字查找
- 有限定的名字查找
- 无限定的名字查找
- 如同规则
- 未定义行为
- 翻译阶段
- 常量表达式
- 赋值运算符
- 算术运算符
- 逻辑运算符
- 成员访问运算符
- 其他运算符
- sizeof 运算符
- typeid 运算符
- 指针声明
- 数组声明
- 语言链接
- 详述类型说明符
- 默认实参
- 变长实参
- 实参依赖查找
- 重载决议
- 重载函数的地址
- 注入类名
- 非静态数据成员
- 非静态成员函数
- 嵌套类
- 派生类
- 空基类优化
- 抽象类
- 位域
- 转换构造函数
- 成员模板
- 模板实参推导
- 部分模板特化
- sizeof... 运算符
- 待决名
- 函数 try 块
- 扩充命名空间 std
- 字母缩写
- RAII
- 三/五/零之法则
- PImpl
- 零开销原则
- 类型
- 隐式转换
- 注释
- C++ 关键词
- 预处理器
- C++ 标准库头文件
- 具名要求
- 功能特性测试 (C++20)
- 工具库
- 类型支持(基本类型、RTTI、类型特性)
- 概念库 (C++20)
- 错误处理
- 动态内存管理
- 日期和时间工具
- 字符串库
- 容器库
- 迭代器库
- 范围库 (C++20)
- 算法库
- 数值库
- 输入/输出库
- 文件系统库
- 本地化库
- 正则表达式库
- 原子操作库
- 线程支持库
- 实验性 C++ 特性
- 有用的资源
- 索引
- std 符号索引
- 协程支持 (C++20)
- C++ 关键词
赋值运算符
赋值运算符修改对象的值。
运算符名 | 语法 | 可重载 | 原型示例(对于 class T) | |
---|---|---|---|---|
类内定义 | 类外定义 | |||
简单赋值 | a = b
|
是 | T& T::operator =(const T2& b); | N/A |
加法赋值 | a += b
|
是 | T& T::operator +=(const T2& b); | T& operator +=(T& a, const T2& b); |
减法赋值 | a -= b
|
是 | T& T::operator -=(const T2& b); | T& operator -=(T& a, const T2& b); |
乘法赋值 | a *= b
|
是 | T& T::operator *=(const T2& b); | T& operator *=(T& a, const T2& b); |
除法赋值 | a /= b
|
是 | T& T::operator /=(const T2& b); | T& operator /=(T& a, const T2& b); |
取模赋值 | a %= b
|
是 | T& T::operator %=(const T2& b); | T& operator %=(T& a, const T2& b); |
逐位与赋值 | a &= b
|
是 | T& T::operator &=(const T2& b); | T& operator &=(T& a, const T2& b); |
逐位或赋值 | a |= b
|
是 | T& T::operator |=(const T2& b); | T& operator |=(T& a, const T2& b); |
逐位异或赋值 | a ^= b
|
是 | T& T::operator ^=(const T2& b); | T& operator ^=(T& a, const T2& b); |
逐位左移赋值 | a <<= b
|
是 | T& T::operator <<=(const T2& b); | T& operator <<=(T& a, const T2& b); |
逐位右移赋值 | a >>= b
|
是 | T& T::operator >>=(const T2& b); | T& operator >>=(T& a, const T2& b); |
|
解释
复制赋值运算符以 b
内容的副本替换对象 a
的内容(不修改 b
)。对于类类型,这是一种特殊成员函数,描述于复制赋值运算符。
移动赋值运算符以 |
(C++11 起) |
对于非类类型,对复制与移动赋值不加以区分,均被称作直接赋值(direct assignment)。
复合赋值(compound assignment)运算符以 a
的值和 b
的值间的二元运算结果替换对象 a
的内容。
内建的直接赋值
直接赋值表达式的形式为
lhs = rhs
|
(1) | ||||||||
lhs = {}
|
(2) | (C++11 起) | |||||||
lhs = { rhs }
|
(3) | (C++11 起) | |||||||
对于内建运算符,lhs 可拥有任何非 const 标量类型,而 rhs 必须可隐式转换为 lhs 的类型。
直接赋值运算符期待以一个可修改左值为其左操作数,以一个右值表达式或花括号初始化器列表 (C++11 起)为其右操作数,并返回一个标识修改后的左运操作的左值。
对于非类类型,首先将右操作数隐式转换为左操作数的无 cv 限定的类型,然后复制其值到左操作数所标识的对象中。
当左操作数拥有引用类型时,赋值运算符修改被引用的对象。
若左右操作数标识的对象之间有重叠,则行为未定义(除非二者严格重叠且类型相同)。
当右运算数为花括号初始化器列表 (brace-init-list)时
|
(C++11 起) |
以 volatile 限定的非类类型左值为内建直接赋值运算符的左操作数被弃用,除非该赋值表达式出现于不求值语境或是弃值表达式。 |
(C++20 起) |
针对用户定义运算符的重载决议中,对于每个类型 T
,下列函数签名参与重载决议:
T*& operator=(T*&, T*); |
||
T*volatile & operator=(T*volatile &, T*); |
||
对于每个枚举或成员指针类型 T
(可选地有 volatile 限定),下列函数签名参与重载决议:
T& operator=(T&, T ); |
||
对于每对 A1 和 A2,其中 A1 是算术类型(可选地有 volatile 限定)而 A2 是提升后的算术类型,下列函数签名参与重载决议:
A1& operator=(A1&, A2); |
||
示例
#include <iostream> int main() { int n = 0; // 不是赋值 n = 1; // 直接赋值 std::cout << n << ' '; n = {}; // 零初始化,然后赋值 std::cout << n << ' '; n = 'a'; // 整型提升,然后赋值 std::cout << n << ' '; n = {'b'}; // 显式转型,然后赋值 std::cout << n << ' '; n = 1.0; // 浮点转换,然后赋值 std::cout << n << ' '; // n = {1.0}; // 编译错误(窄化转换) int& r = n; // 不是赋值 int* p; r = 2; // 通过引用赋值 std::cout << n << '\n'; p = &n; // 直接赋值 p = nullptr; // 空指针转换,然后赋值 struct {int a; std::string s;} obj; obj = {1, "abc"}; // 从花括号初始化器列表赋值 std::cout << obj.a << ':' << obj.s << '\n'; }
输出:
1 0 97 98 1 2 1:abc
内建的复合赋值
复合赋值表达式的形式为
lhs op rhs | (1) | ||||||||
lhs op {} | (2) | (C++11 起) | |||||||
lhs op {rhs} | (3) | (C++11 起) | |||||||
op | - | *=、/=、%=、+=、-=、<<=、>>=、&=、^=、|= 之一 |
lhs | - | 对于内建运算符,lhs 可具有任何算术类型,但若 op 为 += 或 -=,则也接受指针类型,并与 + 和 - 有相同限制 |
rhs | - | 对于内建运算符,rhs 必须可隐式转换为 lhs |
每个内建复合赋值运算符表达式 E1 op= E2(其中 E1 是可修改左值表达式,而 E2 是右值表达式或花括号初始化器列表 (C++11 起))的行为与表达式 E1 = E1 op E2 的行为严格相同,但只对表达式 E1
进行一次求值,并且对于顺序不确定的函数而言是一次单个操作(例如 f(a += b, g()) 中,从 g() 内来看,+= 要么完全未开始,要么已完成)。
以 volatile 限定的非类类型左值为内建复合赋值运算符的左操作数被弃用。 |
(C++20 起) |
在针对用户定义运算符的重载决议中,对每对 A1 和 A2,其中 A1 是算术类型(可选地有 volatile 限定)而 A2 为提升后的算术类型,下列函数签名参与重载决议:
A1& operator*=(A1&, A2); |
||
A1& operator/=(A1&, A2); |
||
A1& operator+=(A1&, A2); |
||
A1& operator-=(A1&, A2); |
||
对于每对 I1 与 I2,其中 I1 是整型类型(可选地有 volatile 限定)而 I2 为提升后的整型类型,下列函数签名参与重载决议:
I1& operator%=(I1&, I2); |
||
I1& operator<<=(I1&, I2); |
||
I1& operator>>=(I1&, I2); |
||
I1& operator&=(I1&, I2); |
||
I1& operator^=(I1&, I2); |
||
I1& operator|=(I1&, I2); |
||
对于每个可选地有 cv 限定的对象类型 T
,下列函数签名参与重载决议:
T*& operator+=(T*&, std::ptrdiff_t); |
||
T*& operator-=(T*&, std::ptrdiff_t); |
||
T*volatile & operator+=(T*volatile &, std::ptrdiff_t); |
||
T*volatile & operator-=(T*volatile &, std::ptrdiff_t); |
||
示例
本节未完成 原因:暂无示例 |
参阅
常见运算符 | ||||||
---|---|---|---|---|---|---|
赋值 | 自增 自减 |
算术 | 逻辑 | 比较 | 成员访问 | 其他 |
a = b |
++a |
+a |
!a |
a == b |
a[b] |
a(...) |
特殊运算符 | ||||||
static_cast 转换一个类型为另一相关类型 |