Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.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
Delphi 为什么我不能对类使用运算符重载?_Delphi_Syntax_Operator Overloading - Fatal编程技术网

Delphi 为什么我不能对类使用运算符重载?

Delphi 为什么我不能对类使用运算符重载?,delphi,syntax,operator-overloading,Delphi,Syntax,Operator Overloading,我在TDateTime中遇到了类运算符的问题 type TDateTime = class(TObject) public class operator Add(a: TDateTime; b: TTimeSpan): TDateTime; class operator Subtract(a: TDateTime; b: TTimeSpan): TDateTime; end; implementation class operator TDateTime.Add(a:

我在TDateTime中遇到了类运算符的问题

type
  TDateTime = class(TObject)
  public
    class operator Add(a: TDateTime; b: TTimeSpan): TDateTime;
    class operator Subtract(a: TDateTime; b: TTimeSpan): TDateTime;
end;

implementation

class operator TDateTime.Add(a: TDateTime; b: TTimeSpan): TDateTime;
begin
  result := TDateTime.Create(a.Ticks + b.Ticks);
end;

class operator TDateTime.Subtract(a: TDateTime; b: TTimeSpan): TDateTime;
begin
  result := TDateTime.Create(a.Ticks - b.Ticks);
end;
错误发生在第四行

E2123预期的过程、函数、属性或变量


我是为Windows写的。但是,如果它仅适用于.net和iOS,我如何才能在Windows上执行此操作?

在Delphi for Windows中,可以仅对记录使用运算符重载,而不对类使用运算符重载


p.S.TDateTime对于用户类型来说是个坏名字。

在桌面版的Delphi(Windows、OSX)中,运算符重载仅适用于记录。对于编译器的移动版本,ARC表示:

类的运算符重载

使用ARC内存管理的一个非常有趣的副作用是编译器可以处理函数返回的临时对象的生存期。一种特殊情况是操作符返回的临时对象。事实上,新的Delphi编译器的一个全新特性是能够使用自Delphi 2006以来可用于记录的相同语法和模型为类定义运算符

如果我没记错的话,操作符重载在现在停止使用的.net编译器中是可用的。这也是可能的,因为.net垃圾收集器可以清理任何临时对象

上面的文档摘录说明了为什么在非ARC版本的类中不能实现运算符重载。如果没有一些自动的生命周期管理,临时类就会泄漏。另一方面,可以在堆栈上的自动存储中创建和销毁临时记录

也就是说,在任何情况下,您的命名有点错误的类型作为值类型可能会更好。因此,您的问题的解决方案是:

  • 给你的类型起一个更好的名字,一个与基本类型不冲突的名字
  • 将您的类型更改为
    记录
    ,这是一种值类型 作为旁注:

    您可以在Delphi.NET编译器中的类上使用它(从那时起已停止),因为.NET垃圾收集将最终删除由运算符返回的新对象实例,最近在基于ARC的Delphi ARM编译器上使用它(该编译器也会根据引用计数释放内存)

    回答你的问题:

    您不能在不支持ARC的本机Delphi编译器中的类上使用它(目前基于Intel的x86和x64编译器Windows、OS X和iOS模拟器不支持ARC),因为它会严重泄漏内存,因为操作员会返回没有人会释放的新对象实例

    随着ARC(目前是基于ARM的移动平台)的引入,您可以像那些编译器一样编译这篇文章

    注:

    • 小心重新定义现有的Delphi类型,如
    • 请注意,您只能在ARC编译器上使用以下命令,因此您正在编写高度依赖于平台的代码
    • 如果您希望跨平台,请将其设置为类似于
      记录的值类型
    在下面的代码(仅适用于ARC)中,将
    替换为
    记录
    使其跨平台。并非巧合,.NET framework的and(您可能基于其编写代码)是值类型,而不是引用类型

    总之,在编写跨平台代码时,请注意值和引用类型,并在使用运算符重载时使用
    记录
    值类型

    type
      TTimeSpan = class
        Ticks: Longint;
      end;
    
      TDateTime = class
      public
        Ticks: Longint;
        class operator Add(a: TDateTime; b: TTimeSpan): TDateTime;
        class operator Subtract(a: TDateTime; b: TTimeSpan): TDateTime;
        constructor Create(aTicks: Longint);
      end;
    
    class operator TDateTime.Add(a: TDateTime; b: TTimeSpan): TDateTime;
    begin
      Result := TDateTime.Create(a.Ticks + b.Ticks);
    end;
    
    constructor TDateTime.Create(aTicks: Integer);
    begin
      Ticks := aTicks;
    end;
    
    class operator TDateTime.Subtract(a: TDateTime; b: TTimeSpan): TDateTime;
    begin
      Result := TDateTime.Create(a.Ticks - b.Ticks);
    end;
    

    知道C++如何在没有自动内存管理的情况下实现类运算符重载吗?这和问题中的代码一样。作为引用类型,它非常糟糕。我希望你不是在支持这一点。你似乎仍然支持在这里使用引用类型。为什么?如果您必须包含代码,那么包含设计良好并在所需平台上运行的代码肯定是有意义的。您的更新会让您回答得更好。我必须说,我真的很想知道为什么你添加了一个与我的答案完全相同的答案。你在补充什么?我遗漏了什么吗?我可能是从你编辑答案的时候开始的。我对此表示怀疑。我的回答一直都是这样的。编辑工作只是小打小闹。不过,选民们似乎更喜欢你的版本