运算符重载

Nik*_*arg 4 c++ java programming-languages language-design

从语言设计的角度来看,什么类型的实践支持运算符重载?

有什么利弊(如果有的话)?

Eva*_*ran 16

编辑:有人提到这std::complex是一个比std::string运算符重载的"好用" 更好的例子,所以我也包括一个例子:

std::complex<double> c;
c = 10.0;
c += 2.0;
c = std::complex<double>(10.0, 1.0);
c = c + 10.0;
Run Code Online (Sandbox Code Playgroud)

除了构造函数语法之外,它的外观和行为与任何其他内置类型一样.


主要的专业是你可以创建像内置类型一样的新类型.一个很好的例子是std::string(在c ++中见上面的更好的例子).这是在库中实现的,不是基本类型.但你可以写下这样的东西:

std::string s = "hello"
s += " world";
if(s == "hello world") {
    //....
}
Run Code Online (Sandbox Code Playgroud)

缺点是容易滥用.运算符重载的选择不当可能导致意外低效或不清楚的代码.想象一下,如果std::list有一个operator[].你可能想写:

for(int i = 0; i < l.size(); ++i) {
    l[i] += 10;
}
Run Code Online (Sandbox Code Playgroud)

这是一个O(n ^ 2)算法!哎哟.幸运的是,std::list 没有,operator[]因为它被认为是一种有效的操作.

  • 为什么这是一个很好的例子?`operator +`对于所有内置类型都是可交换的,但不适用于`std :: basic_string`,所以甚至可以说这是滥用运算符重载.`std :: complex`可能是一个更好的例子. (2认同)

Mar*_*tos 13

最初的驱动程序通常是数学.程序员希望a + b通过向量写入和乘以矩阵来添加向量和四元数M * v.

它的范围要广泛得多.例如,智能指针在语法上看起来像普通指针,流看起来有点像Unix管道,可以使用各种自定义数据结构,就像它们是数组一样(字符串作为索引,甚至!).

重载背后的一般原则是允许库实现者以无缝方式增强语言.这既是力量,也是诅咒.它提供了一种非常强大的方法,使语言看起来比开箱即用更丰富,但它也非常容易被滥用(比许多其他C++功能更多).


Jon*_*eet 6

优点:您最终可以获得更易于阅读的代码.很少有人会认为:

BigDecimal a = x.add(y).divide(z).plus(m.times(n));
Run Code Online (Sandbox Code Playgroud)

就像阅读一样容易

BigDecimal a = ((x + y) / z) + (m * n); // Brackets added for clarity
Run Code Online (Sandbox Code Playgroud)

缺点:很难说出被称为什么.我似乎记得在C++中,表单的声明

a = b[i];
Run Code Online (Sandbox Code Playgroud)

最终可以执行7个自定义操作,但我不记得它们是什么.我可能会稍微"关闭"示例,但原则是正确的 - 运算符重载和自定义转换可以"隐藏"代码.