跳到主要内容

运算符重载

为用户定义类型的操作数定制C++运算符。

语法

重载运算符是具有特殊函数名称的函数

1operator
op
2operator
type
3operator new
operator new []
4operator delete
operator delete []
5operator ""
suffix-identifier (自 C++11 起)
6operator co_await
 (自 C++20 起)
pubop以下任意运算符:+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |=  << >> >>= <<= == != <= >=  <=> (自 C++20 起) && || ++ -- , ->* -> ( ) [ ]
  1. 重载运算符;
  2. 用户定义的转换函数;
  3. 分配函数;
  4. 释放函数;
  5. 用户定义的字面量;
  6. 用于co_await 表达式的重载 co_await 运算符。

重载运算符

当运算符出现在表达式中,并且至少有一个操作数具有类类型或枚举类型时,将使用重载解析来确定要调用的用户定义函数,该函数是所有签名符合以下条件的函数。

表达式作为成员函数作为非成员函数示例
@a(a).operator@ ( )operator@ (a)!std::cin 调用 std::cin.operator!()
a@b(a).operator@ (b)operator@ (a, b)std::cout << 42 调用 std::cout.operator<<(42)
a=b(a).operator= (b)不能是非成员给定 std::string s;s = "abc"; 调用 s.operator=("abc")
a(b...)(a).operator()(b...)不能是非成员给定 std::random_device r;auto n = r(); 调用 r.operator()()
a[b...](a).operator不能是非成员给定 std::map<int, int> m;m[1] = 2; 调用 m.operator[](1)
a->(a).operator-> ( )不能是非成员给定 std::unique_ptr<S> p;p->bar(); 调用 p.operator->()
a@(a).operator@ (0)operator@ (a, 0)给定 std::vector<int>::iterator i;i++ 调用 i.operator++(0)
在此表中,@ 是一个占位符,代表所有匹配的运算符:@a 中的所有前缀运算符,a@ 中的除 -> 之外的所有后缀运算符,a@b 中的除 = 之外的所有中缀运算符。
此外,对于比较运算符 ==!=<><=>=<=>,重载解析还会考虑由 operator==operator<=> 生成的*重写候选*。 (自 C++20 起)

注意:有关重载 co_await (自 C++20 起)用户定义的转换函数用户定义的字面量分配释放,请参阅各自的文章。

重载运算符(但不是内置运算符)可以使用函数表示法调用。

std::string str = "Hello, ";
str.operator+=("world"); // same as str += "world";
operator<<(operator<<(std::cout, str), '\n'); // same as std::cout << str << '\n'
// (since C++17) except for sequencing

限制

  • 无法重载以下运算符::: (作用域解析)、. (成员访问)、.* (指向成员的指针进行成员访问) 和 ?: (三元条件)。
  • 无法创建新运算符,例如 **<>&|
  • 无法更改运算符的优先级、分组或操作数数量。
  • 运算符 -> 的重载必须返回原始指针,或者返回一个其自身运算符 -> 也被重载的对象(通过引用或值)。
  • 运算符 &&|| 的重载会丢失短路求值。
  • 当重载 &&||, (逗号) 运算符时,它们会失去其特殊的排序属性,即使它们在不使用函数调用表示法时也像常规函数调用一样工作。 (C++17 之前)

标准实现

赋值运算符

流提取和插入

函数调用运算符

递增和递减

二进制算术运算符

比较运算符

数组下标运算符

按位算术运算符

布尔否定运算符

很少重载的运算符

备注

示例

缺陷报告

另请参阅

运算符重载

为用户定义类型的操作数定制C++运算符。

语法

重载运算符是具有特殊函数名称的函数

1operator
op
2operator
type
3operator new
operator new []
4operator delete
operator delete []
5operator ""
suffix-identifier (自 C++11 起)
6operator co_await
 (自 C++20 起)
pubop以下任意运算符:+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |=  << >> >>= <<= == != <= >=  <=> (自 C++20 起) && || ++ -- , ->* -> ( ) [ ]
  1. 重载运算符;
  2. 用户定义的转换函数;
  3. 分配函数;
  4. 释放函数;
  5. 用户定义的字面量;
  6. 用于co_await 表达式的重载 co_await 运算符。

重载运算符

当运算符出现在表达式中,并且至少有一个操作数具有类类型或枚举类型时,将使用重载解析来确定要调用的用户定义函数,该函数是所有签名符合以下条件的函数。

表达式作为成员函数作为非成员函数示例
@a(a).operator@ ( )operator@ (a)!std::cin 调用 std::cin.operator!()
a@b(a).operator@ (b)operator@ (a, b)std::cout << 42 调用 std::cout.operator<<(42)
a=b(a).operator= (b)不能是非成员给定 std::string s;s = "abc"; 调用 s.operator=("abc")
a(b...)(a).operator()(b...)不能是非成员给定 std::random_device r;auto n = r(); 调用 r.operator()()
a[b...](a).operator不能是非成员给定 std::map<int, int> m;m[1] = 2; 调用 m.operator[](1)
a->(a).operator-> ( )不能是非成员给定 std::unique_ptr<S> p;p->bar(); 调用 p.operator->()
a@(a).operator@ (0)operator@ (a, 0)给定 std::vector<int>::iterator i;i++ 调用 i.operator++(0)
在此表中,@ 是一个占位符,代表所有匹配的运算符:@a 中的所有前缀运算符,a@ 中的除 -> 之外的所有后缀运算符,a@b 中的除 = 之外的所有中缀运算符。
此外,对于比较运算符 ==!=<><=>=<=>,重载解析还会考虑由 operator==operator<=> 生成的*重写候选*。 (自 C++20 起)

注意:有关重载 co_await (自 C++20 起)用户定义的转换函数用户定义的字面量分配释放,请参阅各自的文章。

重载运算符(但不是内置运算符)可以使用函数表示法调用。

std::string str = "Hello, ";
str.operator+=("world"); // same as str += "world";
operator<<(operator<<(std::cout, str), '\n'); // same as std::cout << str << '\n'
// (since C++17) except for sequencing

限制

  • 无法重载以下运算符::: (作用域解析)、. (成员访问)、.* (指向成员的指针进行成员访问) 和 ?: (三元条件)。
  • 无法创建新运算符,例如 **<>&|
  • 无法更改运算符的优先级、分组或操作数数量。
  • 运算符 -> 的重载必须返回原始指针,或者返回一个其自身运算符 -> 也被重载的对象(通过引用或值)。
  • 运算符 &&|| 的重载会丢失短路求值。
  • 当重载 &&||, (逗号) 运算符时,它们会失去其特殊的排序属性,即使它们在不使用函数调用表示法时也像常规函数调用一样工作。 (C++17 之前)

标准实现

赋值运算符

流提取和插入

函数调用运算符

递增和递减

二进制算术运算符

比较运算符

数组下标运算符

按位算术运算符

布尔否定运算符

很少重载的运算符

备注

示例

缺陷报告

另请参阅