为什么不是';Delphi中的类是否可以使用t运算符重载?

为什么不是';Delphi中的类是否可以使用t运算符重载?,delphi,class,operator-overloading,Delphi,Class,Operator Overloading,我一直在想这个问题,但是为什么Delphi中的类不能使用操作符重载呢 我记得在跑步的时候读过一次答案,上面说它会与某件事发生冲突,但我记不太清楚了。据我所知,只有隐式运算符可能会引起一些问题,因为类存储在堆上,而赋值实际上是堆地址的副本(基本上是复制指针)。关闭。这是因为对象是引用类型,内存是手动管理的。所以如果你说myResult:=myObject1+myObject2+myObject3,您必须在其中的某个位置创建一个中间对象,而没有代码来释放它,因此会出现内存泄漏。Mason Wheel

我一直在想这个问题,但是为什么Delphi中的类不能使用操作符重载呢


我记得在跑步的时候读过一次答案,上面说它会与某件事发生冲突,但我记不太清楚了。据我所知,只有隐式运算符可能会引起一些问题,因为类存储在堆上,而赋值实际上是堆地址的副本(基本上是复制指针)。

关闭。这是因为对象是引用类型,内存是手动管理的。所以如果你说myResult:=myObject1+myObject2+myObject3,您必须在其中的某个位置创建一个中间对象,而没有代码来释放它,因此会出现内存泄漏。

Mason Wheeler说这是不可能的,因为中间对象管理

但根据Embarcadero文档,在可能的情况下,使用Delphi 2009对运算符进行分类


您可以对类进行运算符重载,但仅适用于类使用ARC的下一个编译器。
见:


这是在XE5中引入的,请参见:

编译器可以添加代码来管理字符串,那么为什么它不能处理隐藏对象呢?我不认为这是原因。@mj2008:首先字符串没有,也不能有自定义构造函数。在这种情况下,如果没有使用适当的构造函数和适当的参数来实例化中间对象,那么中间对象很可能是无效的,而编译可能并不总是/永远能够确定这些参数。我怀疑,为支持运算符重载而对类施加的限制将超过其好处。既然你现在可以有“方法记录”,如果你愿意的话,你可以将操作符重载与这些方法结合使用。我明白为什么乍一看它不起作用。但是,编译器不能自动销毁中间对象(本例中最后一个对象除外),然后将赋值视为正常吗?例如,首先创建myIntermediaryObject1作为(myObject1+myObject2)的结果,然后将其与myObject3一起添加创建myIntermediaryObject2,自动销毁myIntermediaryObject1并按常规执行赋值?毕竟,程序员有责任在必要时取消分配myResult,而编译器可以处理其余的临时对象。顺便说一句,“带有方法的记录”的问题是记录没有继承等OOP特性(这基本上也取消了多态性、虚拟方法和所有其他让我们使用类的东西,即使在没有必要的时候)。编译器不能销毁中介对象的原因是它无法知道是否存在任何“中介”对象。运算符可能返回前一次长时间计算中某个缓存对象的实例,或返回操作数对象之一,或返回需要在当前表达式之外继续存在的对象,如表示稍后将在程序中计算的AST的对象。编译器不知道对象来自何处,也不知道以后将使用它做什么。它在Delphi.NET中工作,因为.NET执行垃圾收集。这可以通过两种方式在本机Delphi中解决:1.如果接口上允许使用运算符,则实现这些运算符的类将继承自TInterfacedObject。2.如果将托管类添加到Delphi语言。现在,梅森是对的:你会发现到处都是内存泄漏。另请看我在这个链接上的讲话:是的,我明白为什么这可能被视为一个问题,这正是我在那篇文章中读到的,现在我记起来了。然而,正如我在对梅森回答的评论中所说的,我不认为这实际上是一个问题模仿,我认为只要实现一点垃圾收集(不会有任何副作用),就可以做到这一点。如果intefaces会有运算符,那么会出现很多问题,例如无法取消某些运算符。例如,想象一下,在接口中有一个隐式运算符,然后有一个确实需要该接口但绝对不需要隐式运算符的对象。当您尝试赋值时,所有问题都会发生ght一旦崩溃,就很难发现问题。问题是,如果你想使用“继承的”,运算符永远不应该被继承版本你应该再次重载它,然后进行类型转换。但这意味着类也必须拥有它。至于托管类,这不是记录的类型吗?当然,它们没有继承和所有其他真正定义OOP的功能,但它们可以。是的,你可以将运算符重载作为接口来实现,但这会导致问题它自己的ems。一旦您获取一个TInterfacedObject并将其接口引用计数设置为1,将其视为普通对象就不再安全,因为它将在最后一个接口引用消失后立即消失。运算符重载用于记录。记录是值类型,而类是引用类型。链接中的文档是错误的(虽然他们声明此功能用于记录,但在示例中使用类会失败)。请参阅。这只允许在记录中使用,而不允许在类中使用。但现在使用XE时,记录可以有方法和属性。因此…@所有文档都是这样的,因为.net编译器支持对类进行op重载。可能是因为GC。