【问题标题】:Can I overload operators for my own classes in Delphi?我可以在 Delphi 中为我自己的类重载运算符吗?
【发布时间】:2008-11-30 21:01:25
【问题描述】:

我遇到了一点麻烦——我不知道我是否可以为我的类定义自己的运算符。 例如:

type
  TMinMatrix = class(TMatrix)
    private
      RowAmount: Byte;
      ColAmount: Byte;
      Data: DataMatrix;
      DemVector, SupVector: SupplyDemand;
    public
      constructor Create(Rows, Cols: Byte);
      function GetRowAmount: Byte; override;
      function GetColAmount: Byte; override;
      destructor Destroy;
  end;

我怎么能 - 或者我不能:) - 做类似的事情:

TMinMatrix TMinMatrix::operator=(TMinMatrix* matr)    (c++ code)

顺便问一下,我可以为我的类定义复制构造函数吗?

【问题讨论】:

  • 请更具体一些 - Delphi for Win32 还是 .NET?哪个 Delphi 版本?

标签: delphi oop operators


【解决方案1】:

Delphi Win32 2007 和 2009 仅支持记录的类运算符重载,可以有隐式和显式运算符。 Delphi .Net 支持记录和类的类运算符。

【讨论】:

    【解决方案2】:

    在 Delphi .NET 版本中可能存在运算符重载,旧版本的 Delphi 不支持。

    【讨论】:

    • 运算符重载在 Delphi Win32 2007 和更新的记录中肯定是可能的。但不适合课程,这是正确的。
    【解决方案3】:

    在 Delphi 中复制类的“传统”方法是重写 TPersistant 的“AssignTo”方法。这通常采用

    的形式
    TSubclass(Dest).Field1 := Field1;
    TSubclass(Dest).Field2 := Field2;
    

    这有点痛苦。

    然后 CreateCopy 构造函数将调用此方法:

    constructor CreateCopy(ASource : TMyClass);
    begin
      Create;
      Assign(ASource); // calls AssignTo
    end;
    

    Delphi 后期(2006 年工作)版本中的另一个技巧是使用记录类型来存储字段。

    class TMyClass = class(TPersistent)
    protected
      type  // 2005+ only, otherwise use standalone record
        TMyRecord = record
        Name : string;
        ID : integer;
      end;
    
      FData : TMyRecord;
      procedure AssignTo(Dest : TPersistent);override;
    public
      property Name : string read FData.Name;
      property ID: Integer read FData.ID;
    end;
    
    procedure TMyClass.AssignTo(Dest : TPersistent);
    begin
      if Dest is TMyClass then
         TMyClass(Dest).FData := FData
      else
        inherited; // raise EConvertError
    end;
    

    如果您继续在子类中添加字段,这会变得混乱 - 需要添加新的记录类型,但它会自动处理添加到 TMyrecord 中的新字段(不必记住更新 AssignTo())

    【讨论】:

      【解决方案4】:
      type
        TMinMatrix = class(TMatrix)
          public
            A : integer;
            class operator Add( ATM, BTM : TMinMatrix ) : TMinMatrix;
                // CTM := ATM + BTM
            class operator Subtract( ATM, BTM : TMinMatrix ) : TMinMatrix;
                // CTM := ATM - BTM;
          end;
      
      class operator TMinMatrix.Add( ATM, BTM : TMinMatrix ) : TMinMatrix;
        begin
          result := ATM.A + BTM.A;
        end;
      
      class operator TMinMatrix.Subtract( ATM, BTM : TMinMatrix ) : TMinMatrix;
        begin
          result := ATM.A - BTM.A;
        end;
      
      
      var
        A, B, C : TMinMatrix;
      begin
        C := A + B;  // calls Add()
        C := B - A;  // calls Subtract()
      end.
      

      其他运算符有:

      添加二进制 Add(a: type; b: type): resultType; + 减二进制减法(a:类型;b:类型):resultType; - 乘二乘(a:type;b:type):resultType; * Divide Binary Divide(a: type; b: type) : resultType; / IntDivide Binary IntDivide(a: type; b: type): resultType; div Modulus Binary Modulus(a: type; b: type): resultType;模组 LeftShift Binary LeftShift(a: type; b: type): resultType; shl RightShift Binary RightShift(a: type; b: type): resultType; shr LogicalAnd 二进制 LogicalAnd(a: type; b: type): resultType;和 LogicalOr 二进制 LogicalOr(a: type; b: type): resultType;或者 LogicalXor 二进制 LogicalXor(a: type; b: type): resultType;异或 BitwiseAnd 二进制 BitwiseAnd(a: type; b: type): resultType;和 BitwiseOr 二进制 BitwiseOr(a: type; b: type): resultType;或者 BitwiseXor 二进制 BitwiseXor(a: type; b: type): resultType;异或

      ;)

      【讨论】:

        【解决方案5】:

        无论 Drejc 和 Cesar 怎么说 + 据我所知,Delphi Win32 2007 和 2009 都不支持复制构造函数(我 100% 支持 D2007,但不完全确定 D2009)。

        【讨论】:

          【解决方案6】:

          Delphi Win32 中的运算符重载仅适用于记录,不适用于类。

          它适用于 Delphi 2006 及更高版本,但在 Delphi 2007 中修复了一些错误,使它们更易于使用(与调用运算符结果的函数有关)。

          我在 CodeRage 3 上进行了有关记录运算符重载的会议;您可以在26326 CR3: Nullable Types w/ Records, Methods & Operator Overloading 获取幻灯片和示例代码,和/或在DOWNLOAD VIDEO REPLAY 观看视频回放。

          这是会议摘要:

          具有记录、方法的可空类型 和运算符重载之一 来自数据库的数据和 Delphi原生类型不同,是 对 NULL 的支持。当您与 Delphi中有很多数据库,你想 具有支持 NULL 的数据类型。在 过去你必须使用变体,但是 不再!随着引入 运算符重载,你可以这样做 也有记录类型。本次会议 告诉你怎么做。

          操作符重载仅适用于 Delphi Win32(即非 .NET)中的记录的原因是记录是值类型,因此它们的内存管理是非动态的。类是引用类型,因此需要动态内存分配:它们需要垃圾收集器的概念,以便操作员处理它们。

          由于 Delphi Win32 中没有垃圾收集器的概念,因此在 Delphi Win32 中不可能有类的运算符。

          请注意,CodeRage 4 将于下周开始。它有很多演讲者和会议。

          【讨论】:

            【解决方案7】:

            我认为复制构造函数是一个习惯用法,而不是语言特性。
            所以我可以这样做:
            构造函数 CreateCopy(var t: MyType);

            构造函数 MyType.CreateCopy(var t: MyType);
            开始
            //...
            结束;

            【讨论】:

            • Delphi 更喜欢使用Assign。但是复制构造函数也可以解决问题。
            【解决方案8】:

            Delphi 允许在记录声明中重载某些函数或运算符。你可以在这里看到:http://edn.embarcadero.com/article/34324

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-04-06
              • 1970-01-01
              • 2016-02-29
              • 2019-04-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多