为什么Delphi中的类没有运算符重载?

12

我一直对这个问题有点好奇,但为什么在Delphi中不能为类进行运算符重载?

我记得曾经看过一个回答,它说会与某些东西发生冲突,但我记不清了。据我所知,只有隐式运算符可能会引起一些问题,因为类存储在堆上,而赋值实际上是对堆地址的复制(基本上是复制指针)。


1
它在Delphi.NET中工作是因为.NET进行了垃圾回收。这可以通过两种方式在本地Delphi中解决:1.如果允许在接口上使用运算符,并且实现这些运算符的类将继承自TInterfacedObject。2.如果将托管类添加到Delphi语言中。现在,Mason是正确的:你会在各个地方得到内存泄漏。另请参阅我在此链接上引用的讲话:http://wiert.wordpress.com/2009/10/19/delphi-operator-overloading-table-of-operators-names-and-some-notes-on-usage-and-glitches/ - Jeroen Wiert Pluimers
是的,我明白为什么这可能被视为一个问题,这正是我在那篇文章中读到的,现在我记得了。然而,正如我在对Mason答案的评论中所说的,我认为这实际上并不是一个限制,因为我认为如果你只实现一点垃圾回收(不会产生任何副作用),你就可以做到这一点。 - Cloud737
如果接口有运算符,那么会出现很多问题,例如无法取消某些运算符。例如,在接口中有一个隐式运算符,然后有一个对象需要该接口但绝对不需要隐式运算符。当您尝试进行赋值时,可能会出现问题,很难找到问题所在。 问题是,运算符永远不应该被继承,如果要使用“继承”的版本,则应再次重载它,然后进行类型转换。但这也意味着类也必须拥有它。 - Cloud737
就托管类而言,记录不是有点像吗?当然,它们没有继承和所有其他真正定义面向对象编程的特性,但它们可以。 - Cloud737
1
是的,你可以将操作符重载作为接口实现,但这会带来自身的问题。一旦你将 TInterfacedObject 的接口引用计数设置为 1,就不能再像普通对象一样对待它了,因为它会在最后一个接口引用消失时立即死亡。 - Mason Wheeler
可能是重复的问题:为什么我不能对类使用运算符重载?(http://stackoverflow.com/questions/22541928/why-can-i-not-use-operator-overloading-for-classes) - Johan
3个回答

13

关闭。这是因为对象是引用类型,内存是手动管理的。所以如果你写成myResult := myObject1 + myObject2 + myObject3;,在其中需要创建一个中间对象,但没有释放它的代码,因此会出现内存泄漏。


2
编译器可以添加代码来处理字符串,那么为什么不能处理隐藏对象呢?我不认为这是原因。 - mj2008
我明白为什么乍一看它不起作用。然而,在这种情况下,编译器不能自动销毁中间对象,除了最后一个对象,然后像正常赋值一样处理吗? 例如,首先创建myIntermediaryObject1作为(myObject1 + myObject2)的结果,然后将其与myObject3相加创建myIntermediaryObject2,自动销毁myIntermediaryObject1并像平常一样执行赋值操作? 毕竟,程序员有责任在必要时关注de-allocating myResult,而编译器可以处理其余的临时对象。 - Cloud737
2
编译器无法销毁中间对象的原因是它无法知道是否存在任何“中间”对象。操作符可能会返回先前长时间计算的某个缓存对象的实例,或者可能返回一个操作数对象之一,或者可能返回需要继续存在于当前表达式之外的东西,例如表示稍后将在程序中评估的AST的对象。编译器根本不知道对象来自哪里,以及您将来将用它做什么。 - Rob Kennedy
好的,这已经足够清楚了。:D 感谢您提供所有细节并对我有耐心。 - Cloud737
如果它是一个接口对象,那么问题会得到解决(引用计数)吗?是什么阻止我们能够在实现接口的类上重载运算符? - Bruno Santos
显示剩余4条评论

1

0

运算符重载适用于记录。记录是值类型,而类是引用类型。您链接中的文档是错误的(尽管它们声明此功能适用于记录,但在示例中使用了类)。请参阅 XE3 运算符重载 - LU RD
只有在记录中才允许这样做,而不是在类中。但现在随着XE的出现,记录可以拥有方法和属性。所以... - NaN
1
@所有人,文档的形式是因为.NET编译器支持类的运算符重载。这是由于垃圾回收机制的支持所实现的。 - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接