[C++] 运算符重载
1. Intruduction
通常编程语言使用运算符(Operator)来表示常用的操作和计算,目的是使代码看起来更加简洁清爽。
例如:
x + y * z
要比
add(x, multiply(y, z))
看上去更清晰。
2. Unary/Binary/Ternary Operator
通常编程语言根据操作数(Oprand)的个数对Operator进行分类:
Operator | Number of oprands | Example |
---|---|---|
Unary | 1 | ! |
Binary | 2 | + - * / |
Tenary | 3 | :? (the only one in C++) |
在C++中, Ternay Operator只有一个,即条件运算符。
3. C++ Operator Overloading
3.1 Overloading Binary Operators
对Binary Operator来说,下面两种定义方式是等价的:
- 被定义成只有一个参数的non-static member function;
- 被定义成有两个参数的non-member function;
如果同时定义,将触发overload resolution。下面的代码将触发重载解析错误:
class Foo final {
public:
void operator+(Foo other) {}
};
void operator+(Foo x, Foo y) {}
int main() {
Foo x, y;
x + y;
return 0;
}
// error: ambiguous overload for ‘operator+’ (operand types are ‘Foo’ and ‘Foo’)
3.2 Overloading Unary Operators
对Unary Operator来说,下面两种定义方式是等价的:
- 被定义成没有参数的non-static member function;
- 被定义成只有一个参数的non-member fucntioin;
与Binary Operator相同,如果同时定义,将触发overload resolution。
3.3 Type Conversion Operator
Type Conversion Operator属于Unary Operator,因为有些特殊且较为常用,所以单独拿出来介绍。
在C++中实现Type Conversion从根本上说只有两种方式:
- Constructor
- Conversion Operator
其他方式是这两种方式的包装,例如static_cast()实际上调用二者之一。二者都可以被explicit修饰,是否使用explicit取决于是否希望发生Copy Initialization,这部分内容详见我的另一篇博客:C++ Constructor设计。
使用Constructor实现Type Conversion的问题在于Constructor没有返回值,只能实现别人向自己的转换,不能实现自己向别人的转换。Conversion Operator有返回值,所以这个问题得到了解决。
例如:
class Foo final {
public:
operator bool() { return true; }
};