How to avoid memory leaks with the undocumented operator overloads for classes?

302 Views Asked by At

Delphi has a number of documented operator overloads:

For records and ARC_classes (in the NexGen compiler).
Officially it does not support operator overloading for classes, interfaces or simple types.

Except...

There are undocumented operator overloads that do work on interfaces, classes and simple types.
(Although the undocumented operators do not seem to work on records).

E.g. The following code will compile and works:

Operator overloading for classes in Win32/64

//sorry for the horrible use of `or` to use for nil testing.
//I'd code this into a function (function FirstAssigned(a,b: TObject): TObject;
//It's just an example to demonstrate the concept. 
type
  TObjectHelper = class helper for TObject
  public
    class function &&op_LogicalOr<T: class>(A, B: T): T; static;
  end;

class function TObjectHelper.&&op_LogicalOr<T>(A, B: T): T;
begin
  if A <> nil then
    Result := A
  else
    Result := B;
end;

procedure Test;
var
  sl1, sl2, sl3: TStringList;
begin
  sl1 := nil;
  sl2 := TStringList.Create;
  sl3 := sl1 or sl2; // -> sl3 = sl2
end;

For reference, here is a list of all allowed operators:

List of operators

class operator      class function          example
---------------------------------------------------
Implicit            &&op_Implicit           x:= y;
Explicit            &&op_Explicit           x:= integer(y);
Negative            &&op_UnaryNegation      x:= -y
Positive            &&op_UnaryPlus          x:= +y
Inc                 &&op_Increment          Inc(x);
Dec                 &&op_Decrement          Dec(y);
LogicalNot          &&op_LogicalNot         Not(y); //can be used for bitwise not as well
Trunc               &&op_Trunc              i:= trunc(f);
Round               &&op_Round              i:= round(f);
In                  &&op_In                 if (i in s) then
Equal               &&op_Equality           a = b
NotEqual            &&op_Inequality         a <> b
GreaterThan         &&op_GreaterThan        a > b
GreaterThanOrEqual  &&op_GreaterThanOrEqual a >= b 
LessThan            &&op_LessThan           a < b
LessThanOrEqual     &&op_LessThanOrEqual    a <= b
Add                 &&op_Addition           a + b
Subtract            &&op_Subtraction        a - b
Multiply            &&op_Multiply           a * b
Divide              &&op_Division           a / b //floating point div
IntDivide           &&op_IntDivide          a div b //integer div
Modulus             &&op_Modulus            a mod b
LeftShift           &&op_LeftShift          a shl b
RightShift          &&op_RightShift         a shr b
LogicalAnd          &&op_LogicalAnd         if (a and b) then ...
LogicalOr           &&op_LogicalOr          if (a or b) then ....
LogicalXor          &&op_ExclusiveOr        if (a xor b) then
BitwiseAnd          &&op_BitwiseAnd         x:= a and b
BitwiseOr           &&op_BitwiseOr          x:= a or b
BitwiseXor          &&op_BitwiseXOR         x:= a xor b
Include             &&op_Include            include(s, i);
Exclude             &&op_Exclude            exclude(s, i);

How do I avoid running into memory leaks when using these overloads with (non-arc) classes?

0

There are 0 best solutions below