Lesson 15 · 15 of 20
Operator overloading · Pascal
Define +, * and conversions for your own types with advanced records in Free Pascal: a money type in cents that adds up like a number.

The `{$modeswitch advancedrecords}` directive lets a record have methods and operators, like a small class without Create or Free: it is a value that gets copied on assignment. TMoney stores the amount in whole cents (Int64) so money sums do not drag rounding errors along.
Each `class operator` teaches the compiler to use an operator with the type. + adds two TMoney values and * multiplies a TMoney by a whole quantity. They are implemented as functions: they receive the operands and return the result in Result.
The most interesting one is `:=`, the implicit conversion operator: it says how to turn a Double into a TMoney, rounding to cents. Thanks to it, coffee := 1.60 works, and in coffee * 2 + 3.25 the 3.25 is converted automatically so TMoney's + can be used.
ToString is an ordinary record method. `WriteStr` works like WriteLn but writes into a string, with the same :0:2 formatting, and needs no SysUtils unit. The result reads like a café bill: two coffees and a cake, 6.45 EUR.
Code · main.pas
program main;{$modeswitch advancedrecords}type TMoney = record Cents: Int64; // whole cents: no rounding surprises class operator :=(euros: Double): TMoney; class operator +(a, b: TMoney): TMoney; class operator *(a: TMoney; qty: Integer): TMoney; function ToString: String; end;class operator TMoney.:=(euros: Double): TMoney;begin Result.Cents := Round(euros * 100);end;class operator TMoney.+(a, b: TMoney): TMoney;begin Result.Cents := a.Cents + b.Cents;end;class operator TMoney.*(a: TMoney; qty: Integer): TMoney;begin Result.Cents := a.Cents * qty;end;function TMoney.ToString: String;begin WriteStr(Result, Cents / 100:0:2, ' EUR'); // like WriteLn, into a stringend;var coffee, bill: TMoney;begin coffee := 1.60; // := turns a Double into a TMoney bill := coffee * 2 + 3.25; // *, then + (3.25 is converted too) WriteLn('Coffee: ', coffee.ToString, ' (', coffee.Cents, ' cents)'); WriteLn('2 coffees + 1 cake: ', bill.ToString);end.Output · fpc main.pas && ./main
Coffee: 1.60 EUR (160 cents) 2 coffees + 1 cake: 6.45 EUR
Key points
{$modeswitch advancedrecords}gives records methods and operators.class operator +defines what+does with your type.class operator :=defines an implicit conversion.- A record is a value: it is copied, never created or freed.
- Store money as whole cents.
Exercise
Add class operator <(a, b: TMoney): Boolean and use it to print whether the bill is over 5 EUR; then add - to apply a 0.50 discount.