Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 运算符重载_Java_C++_Programming Languages_Language Design - Fatal编程技术网

Java 运算符重载

Java 运算符重载,java,c++,programming-languages,language-design,Java,C++,Programming Languages,Language Design,从语言设计的角度来看,什么样的实践支持操作符重载 优点和缺点是什么(如果有的话)?优点:您可以得到更易于阅读的代码。很少有人会说: BigDecimal a = x.add(y).divide(z).plus(m.times(n)); 这本书和其他书一样容易阅读 BigDecimal a = ((x + y) / z) + (m * n); // Brackets added for clarity 缺点:很难说出被称为什么。我似乎记得在C++中,表单的语句。 a = b[i]; 最终可以

从语言设计的角度来看,什么样的实践支持操作符重载


优点和缺点是什么(如果有的话)?

优点:您可以得到更易于阅读的代码。很少有人会说:

BigDecimal a = x.add(y).divide(z).plus(m.times(n));
这本书和其他书一样容易阅读

BigDecimal a = ((x + y) / z) + (m * n); // Brackets added for clarity
缺点:很难说出被称为什么。我似乎记得在C++中,表单

的语句。
a = b[i];

最终可以执行7个自定义操作,尽管我不记得它们都是什么。对于这个例子,我可能有点“不同意”,但原理是正确的-运算符重载和自定义转换可以“隐藏”代码。

初始驱动程序通常是数学。程序员希望通过编写
a+b
来添加向量和四元数,并用
M*v
将矩阵乘以向量

它的范围远不止这些。例如,智能指针在语法上看起来像普通指针,流看起来有点像Unix管道,各种自定义数据结构可以像数组一样使用(甚至可以使用字符串作为索引!)


重载背后的一般原则是允许库实现者以无缝的方式增强语言。这既是一种力量,也是一种诅咒。它提供了一种非常强大的方法来让语言看起来比它更富有,但它也非常容易受到滥用(比许多其他C++特性更为重要)。

你可以用语法来做一些有趣的技巧(即C++中的流),这样你可以使一些代码非常简洁。但是,您可能会使代码很难调试和理解。您必须经常警惕不同类型对象的各种运算符的影响。

编辑:有人提到,
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;
缺点是它很容易被滥用。运算符重载中的错误选择可能会导致意外的低效或代码不清晰。想象一下,如果
std::list
有一个
操作符[]
。你可能会想写:

for(int i = 0; i < l.size(); ++i) {
    l[i] += 10;
}
for(int i=0;i

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

您可能认为运算符重载是一种方法/函数重载。它是面向对象语言中多态性的一部分

通过重载,每个对象类都像基本类型一样工作,这使得类的使用更加自然,就像1+2一样简单

说一个复数类,复数。 配合物(1,2i)+配合物(2,3i)生成配合物(3,5i)。 5+络合物(3,2i)产生络合物(8,2i)。 配合物(2,4i)+-1.8产生配合物(0.2,4i)

这样使用类要容易得多。如果没有运算符重载,则必须使用一组类方法来表示“add”,并使表示法变得笨拙


应仔细定义操作员过载;否则,就会出现混乱。例如,“+”运算符用于添加数字、时间、日期或数组或文本的串联。在鼠标或汽车类中添加“+”操作符可能没有任何意义。有时,有些人可能觉得有些超载是不自然的。例如,数组(1,2,3)+数组(3,4,5)。有些人可能会期望数组(4,6,8),但有些期望数组(1,2,3,3,4,5)。

可能的重复C++(<代码> >代码和代码> < /Cord>运算符)是操作符重载的典型坏例子。它们对流的使用与其原始含义无关。@dan04:另一方面,
本身就是非常可怜的内置操作符。它们对于不熟悉C及其同类的人来说没有意义,它们只是为内置类型的子集定义的,即使对于它们处理的类型,结果也不总是定义得很好。它们可能说明了不好的重载,但也说明了为什么指导原则有时可以被很好地使用。“一个很好的例子”带有明显的警告,即为字符串定义运算符+有点讨厌,9为什么这是一个好例子
operator+
对于所有内置类型都是可交换的,但对于
std::basic_string
则不是,因此甚至可以说这是对运算符重载的滥用
std::complex
可能是一个更好的例子。公平地说,
operator+
在语言中很常见,它的意思是“附加”,有时它的方便性被认为比它的一致性更重要。我添加了一个
std::complex
示例。据我所知,只有一个。它应该调用赋值操作符。当然,这可能会调用任意多的其他操作。(
A=b
另一方面,它会调用复制构造函数;))它也可以应用转换。我同意你说它既是一种优势也是一种诅咒,但编程中的每一种优势都是一种诅咒,不是吗?任何东西都可能被滥用。运算符重载允许程序员创建更糟糕的接口,允许设置变量(命令式编程)允许程序员创建错误的变量名,反射允许程序员弄乱他们的objectcontext,调试器使程序员不那么小心,IDE使程序员懒惰。我认为所有这些都会对编程产生积极的影响,但是它们都有被滥用的可能。@ B:这些都是母性的陈述。如果任何东西都可以被描述为力量和诅咒,那么这个短语就变得毫无意义。显然,我的意图是传达这样一个概念,即操作符重载特别容易被滥用,以至于设置变量、创建数组、循环迭代或调用函数的能力都不具备。
for(int i = 0; i < l.size(); ++i) {
    l[i] += 10;
}