我可以在Delphi中为自己的类重载运算符吗?

时间:2008-11-30 21:01:26

标签: delphi oop operators

我遇到了一些麻烦 - 我不知道我是否可以为我的课程定义自己的操作符。 例如:

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)

顺便说一句,我可以为我的班级定义复制构造函数吗?

8 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:3)

在Delphi .NET版本中可以进行运算符重载,旧版本的Delphi不支持它。

答案 2 :(得分:2)

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

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

这有点痛苦。

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

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

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

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())

答案 3 :(得分:2)

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        Binary   Add(a: type; b: type): resultType;         +   
Subtract   Binary   Subtract(a: type; b: type) : resultType;   -   
Multiply   Binary   Multiply(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;     mod   
LeftShift  Binary   LeftShift(a: type; b: type): resultType;   shl   
RightShift Binary   RightShift(a: type; b: type): resultType;  shr   
LogicalAnd Binary   LogicalAnd(a: type; b: type): resultType;  and   
LogicalOr  Binary   LogicalOr(a: type; b: type): resultType;   or   
LogicalXor Binary   LogicalXor(a: type; b: type): resultType;  xor   
BitwiseAnd Binary   BitwiseAnd(a: type; b: type): resultType;  and   
BitwiseOr  Binary   BitwiseOr(a: type; b: type): resultType;   or   
BitwiseXor Binary   BitwiseXor(a: type; b: type): resultType;  xor   

答案 4 :(得分:1)

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

答案 5 :(得分:1)

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下周开始。它有一个很好的演讲者和会议阵容。

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

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