Delphi 中记录操作重载(Operator Overloading)

一、关于记录操作重载

        Delphi 允许在记录声明中重载某些函数或 "操作符"。操作符函数的名称映射到源代码中的符号表示。例如,Add 运算符映射到 + 符号。

        编译器会根据操作符函数的名称,生成对相应重载的调用,并匹配上下文(即返回类型和调用中使用的参数类型)。

        下表列出了可以重载的 Delphi 运算符: 

OperatorCategoryDeclaration SignatureSymbol Mapping

Implicit

Conversion

Implicit(a : type) : resultType;

implicit typecast

Explicit

Conversion

Explicit(a: type) : resultType;

explicit typecast

Negative

Unary

Negative(a: type) : resultType;

-

Positive

Unary

Positive(a: type): resultType;

+

Inc

Unary

Inc(a: type) : resultType;

Inc

Dec

Unary

Dec(a: type): resultType

Dec

LogicalNot

Unary

LogicalNot(a: type): resultType;

not

Trunc

Unary

Trunc(a: type): resultType;

Trunc

Round

Unary

Round(a: type): resultType;

Round

In

Set

In(a: type; b: type) : Boolean;

in

Equal

Comparison

Equal(a: type; b: type) : Boolean;

=

NotEqual

Comparison

NotEqual(a: type; b: type): Boolean;

<>

GreaterThan

Comparison

GreaterThan(a: type; b: type) Boolean;

>

GreaterThanOrEqual

Comparison

GreaterThanOrEqual(a: type; b: type): Boolean;

>=

LessThan

Comparison

LessThan(a: type; b: type): Boolean;

<

LessThanOrEqual

Comparison

LessThanOrEqual(a: type; b: type): Boolean;

<=

Assign

Binary

Assign(var Dest: type; const [ref] Src: type);

:=

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

        除表中列出的操作符外,记录中不得定义其他操作符。

        重载的操作符方法不能在源代码中通过名称引用。要访问特定记录的特定操作符方法,请参阅 下面示例)。运算符标识符包含在以 "运算符 "开头的语言记录方法列表中(例如:System.AnsiStringBase 方法)。您可以在自己的记录中实现上述任何操作符。

         只要符合以下条件,编译器就会为记录使用运算符:

  • 对于二元运算符,其中一个输入参数必须是记录类型。
  • 对于一元运算符,输入参数或返回值必须是记录类型。
  • 对于使用相同符号的逻辑运算符和位运算符,逻辑运算符仅在操作数为布尔时使用。由于此记录运算符的记录类型不是布尔型,因此只有当另一个操作数是布尔型时,才会使用逻辑运算符。

不对运算的分配或交换性质做任何假设。对于二元运算符,第一个参数总是左操作数,第二个参数总是右操作数。在没有明确括号的情况下,关联性被假定为从左到右。

操作符方法的解析是在操作中使用的类型的可访问操作符的联合体上完成的(注意这包括继承操作符)。对于涉及两个不同类型 A 和 B 的操作,如果 A 类型隐式转换为 B 类型,而 B 类型隐式转换为 A 类型,就会产生歧义。只有在绝对必要的情况下才提供隐式转换,并应避免反向性。最好让 B 类型隐式地转换为 A 类型,而让 A 类型不知道 B 类型(反之亦然)。

一般来说,操作符不应修改其操作数。相反,应通过对参数执行操作来返回一个新值。

重载操作符最常用于记录(即值类型)。
 

注意:记录助手(Record helpers)不支持操作符重载。

二、声明操作符重载

操作符重载在记录中声明,语法如下:

type
   typeName = record
       class operator conversionOp(a: type): resultType;
       class operator unaryOp(a: type): resultType;
       class operator comparisonOp(a: type; b: type): Boolean;
       class operator binaryOp(a: type; b: type): resultType;
   end;

重载操作符的实现也必须包含类操作符(class operator)语法: 

class operator typeName.conversionOp(a: type): resultType;
class operator typeName.unaryOp(a: type): resultType;
class operator typeName.comparisonOp(a: type; b: type): Boolean;
class operator typeName.binaryOp(a: type; b: type): resultType;

下面是一些重载操作符的示例: 

type
   TMyRecord = record
     class operator Add(a, b: TMyRecord): TMyRecord;      // Addition of two operands of type TMyRecord
     class operator Subtract(a, b: TMyRecord): TMyRecord; // Subtraction of type TMyRecord
     class operator Implicit(a: Integer): TMyRecord;      // Implicit conversion of an Integer to type TMyRecord
     class operator Implicit(a: TMyRecord): Integer;      // Implicit conversion of TMyRecordto Integer
     class operator Explicit(a: Double): TMyRecord;       // Explicit conversion of a Double to TMyRecord
   end;

// Example implementation of Add
class operator TMyRecord.Add(a, b: TMyRecord): TMyRecord;
begin
   // ...
end;

var
x, y: TMyRecord;
begin
   x := 12;      // Implicit conversion from an Integer
   y := x + x;   // Calls TMyRecord.Add(a, b: TMyRecord): TMyRecord
   b := b + 100; // Calls TMyRecord.Add(b, TMyRecord.Implicit(100))
end;

再举一个示例:

TPassphrase = record
  private
    FType: TPassphraseType;
    FValue: TBytes;
    FKey: TBytes;
    FInitVector: TBytes;
  public
    class operator Implicit(const Value: string): TPassphrase;
    class operator Implicit(const Value: TBytes): TPassphrase;
    constructor Create(const Key, InitVector: TBytes); overload;
    constructor Create(const Password: string; Encoding: TEncoding); overload;
  end;

{ TPassphrase }

class operator TPassphrase.Implicit(const Value: string): TPassphrase;
begin
  Result.FType := ptPassword;
  Result.FValue := TEncoding.UTF8.GetBytes(Value);
end;

class operator TPassphrase.Implicit(const Value: TBytes): TPassphrase;
begin
  Result.FType := ptPassword;
  Result.FValue := Value;
end;

constructor TPassphrase.Create(const Key, InitVector: TBytes);
begin
  FType := ptKeys;
  FKey := Key;
  FInitVector := InitVector;
end;

constructor TPassphrase.Create(const Password: string; Encoding: TEncoding);
begin
  FType := ptPassword;
  FValue := Encoding.GetBytes(Password);
end;

使用如下:

var
  Password: TBytes


FCipher.Passphrase:=Password;  

//以上调用 class operator Implicit(const Value: TBytes): TPassphrase;

       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海纳老吴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值