1

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

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)

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

4

8 回答 8

5

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

于 2008-11-30T21:30:32.617 回答
3

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

于 2008-11-30T21:19:29.317 回答
2

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

于 2008-12-01T02:55:48.060 回答
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(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 Binary 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; 异或   

;)

于 2009-09-05T23:10:13.100 回答
1

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

于 2008-11-30T21:51:17.927 回答
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 将于下周开始。它有一个很好的演讲者和会议阵容。

于 2009-09-06T15:33:37.290 回答
0

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

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

于 2008-12-01T01:21:39.623 回答
0

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

于 2010-03-17T13:12:48.407 回答