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
defaultproperties 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 + blooks 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…