zoukankan      html  css  js  c++  java
  • Delphi中record 的运算符重载

    -----------------------------------

    Delphi中目前好像只能在Record中定义运算法重载的方法,C++的运算符重载定义在类中,有区别,以后有啥研究再记录下来,方便学习交流

    ---------------------------------------

    资料来源:delphi 中record 的类操作符重载简介 - findumars - 博客园  https://www.cnblogs.com/findumars/p/10201381.html

    Operator Overloading (Delphi) - RAD Studio  http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Operator_Overloading_(Delphi)

    TXalionRec=record
    ival:integer;
    dval:Tdatetime;
    constructor create(s:string);
    {destructor Destroy;}

    //class operator Assign(var Dest:TXalionRec;const Src:TXalionRec); // 赋值

    class operator NotEqual(ALeft,ARight:TXalionRec):boolean; // 不等于
    class operator Equal(ALeft,ARight:TXalionRec):boolean; //等于
    class operator GreaterThan(ALeft,ARight:TXalionRec):boolean; // 大于
    class operator GreaterThanOrEqual(ALeft,ARight:TXalionRec):boolean; //大于等于
    class operator LessThan(ALeft,ARight:TXalionRec):boolean; // 小于
    class operator LessThanOrEqual(ALeft,ARight:TXalionRec):boolean; //小于等于
    class operator Inc(AValue:TXalionRec):TXalionRec; // 递增
    class operator Dec(AValue:TXalionRec):TXalionRec; // 递减

    class operator Add(AValue1:TXalionRec; AValue2:integer):TXalionRec; // 加整数
    class operator Add(AValue1:TXalionRec; AValue2:TDateTime):TXalionRec; //加时间
    class operator Add(AValue1:TXalionRec; AValue2:TXalionRec):TXalionRec; // 直接加


    class operator Implicit(AValue:TDateTime):TXalionRec; //显式等于日期
    class operator Implicit(AValue:integer):TXalionRec; //显式等于整数

    class operator Implicit(AValue:TXalionRec):TDateTime; //显式赋值日期
    class operator Implicit(AValue:TXalionRec):integer; //显式赋值整数
    end;

    {class operator TXalionRec.Assign(var Dest:TXalionRec;const Src:TXalionRec);
    begin
    dest.ival:=src.ival;
    dest.dval:=src.dval;
    end; }

    class operator TXalionRec.Add(AValue1: TXalionRec;
    AValue2: TDateTime): TXalionRec;
    begin
    result:= AValue1;
    result.dval:=result.dval+avalue2;
    end;

    class operator TXalionRec.Add(AValue1: TXalionRec;
    AValue2: integer): TXalionRec;
    begin
    result:= AValue1;
    result.ival:=result.ival+avalue2;
    end;

    class operator TXalionRec.Add(AValue1:TXalionRec; AValue2:TXalionRec):TXalionRec;
    begin
    result.ival :=avalue1.ival+avalue2.ival;
    result.dval:= avalue1.dval+avalue2.dval;
    end;

    constructor TXalionRec.create(s:string);
    begin
    ival:=0;
    dval:=now;
    end;

    class operator TXalionRec.Dec(AValue: TXalionRec): TXalionRec;
    begin
    result:=Avalue;
    dec(result.ival);
    end;

    {destructor TXalionRec.Destroy;
    begin
    exit;
    end; }

    class operator TXalionRec.Equal(ALeft, ARight: TXalionRec): boolean;
    begin
    result:=False;
    if Aleft.ival=Aright.ival then
    begin
    result:=True;
    end;

    end;

    class operator TXalionRec.GreaterThan(ALeft, ARight: TXalionRec): boolean;
    begin
    result:=False;
    if Aleft.ival>Aright.ival then
    result:=True;
    end;

    class operator TXalionRec.GreaterThanOrEqual(ALeft,
    ARight: TXalionRec): boolean;
    begin
    result:=False;
    if Aleft.ival>=Aright.ival then
    result:=True;
    end;

    class operator TXalionRec.Implicit(AValue: integer): TXalionRec;
    begin
    result.ival:=Avalue;
    end;

    class operator TXalionRec.Implicit(AValue: TDateTime): TXalionRec;
    begin
    result.dval:=Avalue;
    end;

    class operator TXalionRec.Implicit(AValue: TXalionRec): integer;
    begin
    result:=Avalue.ival;
    end;

    class operator TXalionRec.Implicit(AValue: TXalionRec): TDateTime;
    begin
    result:=Avalue.dval;
    end;

    class operator TXalionRec.Inc(AValue: TXalionRec): TXalionRec;
    begin
    result:=Avalue;
    inc( result.ival);
    end;

    class operator TXalionRec.LessThan(ALeft, ARight: TXalionRec): boolean;
    begin
    result:=False;
    if Aleft.ival<Aright.ival then
    result:=True;
    end;

    class operator TXalionRec.LessThanOrEqual(ALeft, ARight: TXalionRec): boolean;
    begin
    result:=False;
    if Aleft.ival<=Aright.ival then
    result:=True;
    end;

    class operator TXalionRec.NotEqual(ALeft, ARight: TXalionRec): boolean;
    begin
    result:=False;
    if Aleft.ival<>Aright.ival then
    result:=True;
    end;

    procedure TForm1.Button3Click(Sender: TObject);
    var
    myrec,rec2:TXalionRec;
    d:Tdatetime;
    begin
    myrec:=3; //等于整数
    memo1.Lines.Add('myrec ival='+ IntToStr(myrec.ival));
    memo1.Lines.Add('myrec dval='+ formatdatetime('yyyy-mm-dd',myrec.dval));
    memo1.Lines.Add('>>>>>>>>>>>>>>>>>>end<<<<<<<<<<<<<<<<');


    inc(myrec); //递增
    memo1.Lines.Add('myrec ival='+ IntToStr(myrec.ival)); //myrec.ival.ToString
    memo1.Lines.Add('myrec dval='+ formatdatetime('yyyy-mm-dd',myrec.dval));
    memo1.Lines.Add('>>>>>>>>>>>>>>>>>>end<<<<<<<<<<<<<<<<');

    d:=2;
    myrec:=myrec+ d; //加时间 2天
    memo1.Lines.Add('myrec ival='+ IntToStr(myrec.ival));
    memo1.Lines.Add('myrec dval='+ formatdatetime('yyyy-mm-dd',myrec.dval));
    memo1.Lines.Add('>>>>>>>>>>>>>>>>>>end<<<<<<<<<<<<<<<<');


    myrec:=myrec+5; //加整数

    memo1.Lines.Add('myrec ival='+ IntToStr(myrec.ival));
    memo1.Lines.Add('myrec dval='+ formatdatetime('yyyy-mm-dd',myrec.dval));
    memo1.Lines.Add('>>>>>>>>>>>>>>>>>>end<<<<<<<<<<<<<<<<');

    rec2:=6;

    myrec:=myrec+rec2;


    memo1.Lines.Add('myrec ival='+ IntToStr(myrec.ival));
    memo1.Lines.Add('myrec dval='+ formatdatetime('yyyy-mm-dd',myrec.dval));
    memo1.Lines.Add('>>>>>>>>>>>>>>>>>>end<<<<<<<<<<<<<<<<');


    end;

    -------------------------------------------资料还是保存下----------------开始--------------

    About Operator Overloading

    Delphi allows certain functions, or "operators", to be overloaded within record declarations. The name of the operator function maps to a symbolic representation in source code. For example, the Add operator maps to the + symbol.

    The compiler generates a call to the appropriate overload, matching the context (that is, the return type, and type of parameters used in the call), to the signature of the operator function.

    The following table shows the Delphi operators that can be overloaded:

    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;

    <=

    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


    No operators other than those listed in the table may be defined on a class or record.

    Overloaded operator methods cannot be referred to by name in source code. To access a specific operator method of a specific class or record, refer to: Code Example:OpOverloads_(Delphi). Operator identifiers are included for classes and records in the language in the class or record's list of methods starting with the word "operator" (example: System.AnsiStringBase Methods). You can implement any of the above operators in your own classes and records.

    The compiler will use an operator for a class or record provided that:

    • For binary operators, one of the input parameters must be the class type.
    • For unary operators, either the input parameter or the return value must be the class type.
    • For a logical operator and a bitwise operator using the same symbol, the logical operator is used only when the operands are booleans. Since the type of the class of this class operator is not a boolean, a logical operator will only be used when the other operand is a boolean.

    No assumptions are made regarding the distributive or commutative properties of the operation. For binary operators, the first parameter is always the left operand, and the second parameter is always the right operand. Associativity is assumed to be left-to-right in the absence of explicit parentheses.

    Resolution of operator methods is done over the union of accessible operators of the types used in the operation (note this includes inherited operators). For an operation involving two different types A and B, if type A has an implicit conversion to B, and B has an implicit conversion to A, an ambiguity will occur. Implicit conversions should be provided only where absolutely necessary, and reflexivity should be avoided. It is best to let type B implicitly convert itself to type A, and let type A have no knowledge of type B (or vice versa).

    As a general rule, operators should not modify their operands. Instead, return a new value, constructed by performing the operation on the parameters.

    Overloaded operators are used most often in records (that is, value types).

    Note: Class and record helpers do not support operator overloading.

    Declaring Operator Overloads

    Operator overloads are declared within classes or records, with the following syntax:

    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;
    

    Implementation of overloaded operators must also include the class operator syntax:

    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;
    

    The following are some examples of overloaded operators:

    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;

    -------------------------------------------资料还是保存下------------------结束-----------

  • 相关阅读:
    vs c++配置opencv(1)
    vs2013搭建团队版本控制 TFS、SVN
    robomongo
    Node log4js
    node.async.auto
    p2.js物理引擎学习
    pomelo
    Node.mongoose
    Node.Buffer
    Node安装及搭建简单HTTP服务器
  • 原文地址:https://www.cnblogs.com/dmqhjp/p/15029052.html
Copyright © 2011-2022 走看看