Is there anyway to use the property like behavior?

前端 未结 3 1261
终归单人心
终归单人心 2021-01-29 12:11

I have the following formula

X := X + F*(1-i div n);

Where

X, F, i, n: integer;

The code I\'m using is this<

相关标签:
3条回答
  • 2021-01-29 12:44

    I found a way to do what I wanted. I know that overloading the := operator is not possible, However forcing the compiler to produce the same behavior as the overloaded operator would behave is possible.

    The overloading would not let me control the LSA (Left Side Argument). but it gave full control to implicitly convert any TType (in my case it is an integer) to TXinteger. So all I had to do is make sure that every operator would result in a TType which will force the compiler to implicitly convert that to a TXinteger.

    Forcing the compiler to use my implicit operator every time it wants to assign something to TXinteger means I control the assignment Hence I overloaded the := operator.

    the following is a test example that makes omitting Line(1) possible.

    program Project4;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      System.SysUtils;
    
    
    
    type
       TXinteger = record
         X: integer;
         class operator Add(a, b: TXinteger): integer;
         class operator Add(a: TXinteger; b:integer): integer;
         class operator Add(a: integer; b:TXinteger): integer;
         class operator Implicit(a: Integer): TXinteger;
         class operator Implicit(a: TXinteger): Integer;
       end;
    
    // Example implementation of Add
    class operator TXinteger.Add(a, b: TXinteger): integer;
    begin
      result := a.X + b.X;
    end;(**)
    
    class operator TXinteger.Add(a: TXinteger; b:integer): integer;
    begin
      result := a.X + b;
    end;
    
    class operator TXinteger.Add(a: integer; b:TXinteger): integer;
    begin
      result := a + b.X;
    end;
    
    class operator TXinteger.Implicit(a: Integer): TXinteger;
    const
      Xmax: integer = 10;
    begin
      if a > Xmax then result.X := 0 else result.X := a;
    end;
    
    class operator TXinteger.Implicit(a: TXinteger): Integer;
    begin
      result := a.X;
    end;
    
    var
    X: TXinteger;
    Hn, F, i,J, n: integer;
    begin
      try
      F := 7;
      n := 10;
      Hn := n * 2 ;
      X := 0;
      i := 1;
      J := 1;
      while J < Hn do
        begin
        X := X + F * (1 - i div n);
        // Line (1)  is gone now.
        if i >= n then Dec(i)
        else Inc(i);
        Inc(J);
        end;
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end.
    

    Note: for this case it is pointless to do all of this just to omit one line of code. I wanted to share this because it gives an idea of how one could overload the := operator.

    What I wanted is this:

    • Alter how X:Integer is read (value read from the variable x's storage).
    • Alter how X:Integer is assigned.

    by overloading all the operators that use the value of X, I completed the first. And by forcing the compiler as explained above, I completed the second.

    Thank you all for your help.

    0 讨论(0)
  • 2021-01-29 12:52

    Is there anyway to use the property like approach outside a class/record?

    No, property getters and setters can only be implemented in records and classes.

    0 讨论(0)
  • 2021-01-29 12:54

    You can use local function like

    procedure YourProcedure;
    
    var
      X: Integer;
      LJ: Integer;
    function J: Integer;
    begin
      Inc(LJ);
      Result := LJ;
    end; 
    procedure SetX(const AValue: Integer);
    const
      Xmax: SomeIntegerValue;
    begin
      if aValue > Xmax then X := 0  
      else X := aValue; 
    end;
    //...
    begin
      while J < Hn do  // J will be incremented each time the loop wants to  read it.    
      begin
         SetX(X + F * (1 - i div n));
      end
    end.
    
    0 讨论(0)
提交回复
热议问题