Skip to content
Operator Overloading
step 1/4

Reading — step 1 of 4

Learn

~2 min readInterfaces, Operators, Idiomatic FPC

FreePascal supports operator overloading — define what +, -, *, =, etc. mean for your types.

Overloading for records

type
    TVector = record
        X, Y: real;
        class operator + (a, b: TVector): TVector;
        class operator - (a, b: TVector): TVector;
        class operator * (a: TVector; scalar: real): TVector;
        class operator = (a, b: TVector): boolean;
    end;

class operator TVector.+ (a, b: TVector): TVector;
begin
    Result.X := a.X + b.X;
    Result.Y := a.Y + b.Y;
end;

FPC supports class operator inside records (and classes, with {$mode delphiunicode} etc.).

Free-standing operator overloading

For older FPC modes, operators can be defined free-standing:

operator + (a, b: TVector) c: TVector;
begin
    c.X := a.X + b.X;
    c.Y := a.Y + b.Y;
end;

Using

var a, b, c: TVector;
begin
    a.X := 1; a.Y := 2;
    b.X := 3; b.Y := 4;
    c := a + b;
    WriteLn(Format('(%g, %g)', [c.X, c.Y]));     { (4, 6) }
end.

Common overloadable operators

  • Arithmetic: +, -, *, /, div, mod
  • Unary: - (negate), + (positive)
  • Comparison: =, <>, <, >, <=, >=
  • Logical: and, or, xor, not
  • Conversion: Implicit, Explicit (cast operators)
  • Index: not directly, but you can define default properties on classes

Implicit conversion

Let your type silently convert to/from another:

class operator TMoney.Implicit (m: TMoney): real;
begin
    Result := m.Cents / 100.0;
end;

class operator TMoney.Implicit (r: real): TMoney;
begin
    Result.Cents := Round(r * 100);
end;

// Now you can:
var m: TMoney;
begin
    m := 5.99;            { real → TMoney }
    WriteLn(m * 1.0);     { TMoney → real (via *) }
end.

Use cases

  • Math types: vectors, matrices, complex numbers
  • Financial: Money type that wraps Currency or scaled int
  • Domain wrappers: Distance, Temperature with unit safety
  • DSL-style APIs

Caveats

  • Operator overloading hides the cost of operations — a + b looks like a primitive op but might allocate, copy, or take milliseconds
  • Overuse makes code harder to follow — be conservative
  • Inconsistent semantics (+ doing something weird) is confusing — only overload when meaning is intuitive

When to skip operator overloading

For simple data types where readability of Math.Add(a, b) is fine, just use named methods. Operators shine for math, comparison, and casts where the syntax really helps.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…