从C++到Java,一个明显的悬而未决的问题是,为什么Java不包括运算符重载?
Complex a, b, c; a = b + c;
不是比Complex a, b, c; a = b.add(c);
简单得多吗?
有没有一个已知的原因,不允许操作符重载的有效参数?原因是武断的,还是迷失在时间中?
发布于 2008-09-16 22:31:08
假设您想要覆盖a
引用的对象的先前值,则必须调用一个成员函数。
Complex a, b, c;
// ...
a = b.add(c);
在C++中,此表达式告诉编译器在堆栈上创建三(3)个对象,执行加法,并将结果值从临时对象复制到现有对象a
中。
然而,在Java语言中,operator=
不会对引用类型执行值复制,用户只能创建新的引用类型,而不能创建值类型。因此,对于名为Complex
的用户定义类型,赋值意味着复制对现有值的引用。
相反,请考虑:
b.set(1, 0); // initialize to real number '1'
a = b;
b.set(2, 0);
assert( !a.equals(b) ); // this assertion will fail
在C++中,这将复制值,因此比较结果将不相等。在Java语言中,operator=
执行引用复制,因此a
和b
现在引用相同的值。因此,比较将产生“相等”,因为对象将与其自身进行比较。
副本和引用之间的差异只会增加运算符重载的混乱。正如@Sebastian提到的,operator+
和C#都必须分别处理值和引用相等-- operator+
很可能会处理值和对象,但operator=
已经实现来处理引用。
在C++中,您一次只能处理一种比较,因此可以减少混淆。例如,在Complex
上,operator=
和operator==
都在处理值--分别复制值和比较值。
发布于 2008-09-17 13:01:51
查看Boost.Units:link text
它通过操作符重载提供零开销维度分析。这还能变得更清楚吗?
quantity<force> F = 2.0*newton;
quantity<length> dx = 2.0*meter;
quantity<energy> E = F * dx;
std::cout << "Energy = " << E << endl;
实际上会输出"Energy =4J“,这是正确的。
发布于 2008-09-16 22:11:52
Java设计者认为操作符重载带来的麻烦比它的价值更大。就这么简单。
在这样一种语言中,每个对象变量实际上都是一个引用,操作符重载带来了非常不合逻辑的额外风险-至少对C++程序员来说是这样。将这种情况与C#的==操作符重载以及Object.Equals
和Object.ReferenceEquals
(或其他名称)进行比较。
https://stackoverflow.com/questions/77718
复制相似问题