重载
C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。
函数重载
利用函数重载,你可以根据参数(和返回值类型无关)的类型和数量为函数提供不同的语义。例如:
#include <iostream>
int volume(int s) { // 立方体的体积。
return s * s * s;
}
double volume(double r, int h) { // 圆柱体的体积。
return 3.1415926 * r * r * static_cast<double>(h);
}
long volume(long l, int b, int h) { // 长方体的体积。
return l * b * h;
}
int main() {
std::cout << volume(10) << endl;
std::cout << volume(2.5, 8) << endl;
std::cout << volume(100l, 75, 15) << endl;
}
编译器会根据一定规则,决定volume
应该调用哪一个具体的实现。
Rust并没有函数重载。所以类似的代码在Rust中可能会叫
cube_volume
,cubic_volume
,cylinder_volume
。
运算符重载
重载运算符是通过对运算符的重新定义,使得其支持特定数据类型的运算操作。运算符重载本质上也是函数重载,它们可以看做函数名为 operator+
、operator-
、operator*
、operator++
、operator<<
等等的函数。
重载运算符存在如下限制:
- 只能对现有的运算符进行重载,不能自行定义新的运算符。
- 以下运算符不能被重载:
::
(作用域解析),.
(成员访问),.*
(通过成员指针的成员访问),?:
(三目运算符)。 - 重载后的运算符,其运算优先级,运算操作数,结合方向不得改变。
- 对
&&
(逻辑与)和||
(逻辑或)的重载失去短路求值。
以重载比较运算符为例。在使用STL容器和算法的时候,我们经常需要用到<
运算符(只重载 <
运算符在某些情况下已足够,例如使用std::sort
,但完整地支持所有比较通常是一个好的实践。)
struct Time {
int time;
int num;
bool operator<(const Time &other) const {
if (time == other.time) {
return num < other.num;
}
return time < other.time;
}
};
一些资料会说Rust没有重载,实际上他指的是函数重载。Rust是支持实现运算符重载的功能的。参考core::ops。并且不同于C++,Rust对比较运算符的重载必须是自洽的。