Operator overloading is a very nice feature of the Delphi language.
However. the Delphi documentation on Operator overloading is not completely right.
Below is my table of what I found out so far, and some notes.
It is part of my “Nullable types in Delphi” session that I gave on some conferences.
The downloads for that session contain more detailed information.
This is just an abstract to get you going and a try to answer this operator overloading question on Stackoverflow.
Download the full presentation to get more in depth information.
Let me know if you need more information.
Notes
Operator overloading
Add your own “behaviour” to operators
- Win32: Works only for records, not classes!
- An operator and the operand(s)
are being implemented worden by a “class operator”;
this is a kind of class method with name and argumen(s)
Example:
- Multiplication X : = A * B;
- Operator: *
- Name: Multiply
- Operands: 2 -> two parameters
type TMyRecord = record class operator Multiply(A, B: TMyRecord): TMyRecord; end;
Documentation is not correct!
- http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/operatoroverloads_xml.html
http://docwiki.embarcadero.com/RADStudio/2010/en/IDEIds03
http://docwiki.embarcadero.com/RADStudio/2010/en/Operator_Overloading
http://docwiki.embarcadero.com/RADStudio/XE/en/IDEIds03
http://docwiki.embarcadero.com/RADStudio/XE2/en/IDEIds03
http://docwiki.embarcadero.com/RADStudio/XE3/en/IDEIds03 - Win32 only records; .NET classes and records
- BitwiseNot does not exist (use LogicalNot)
As of Delphi XE1, it has been fixed in some pages of the docs:
http://docwiki.embarcadero.com/RADStudio/XE/en/Operator_Overloading
http://docwiki.embarcadero.com/RADStudio/XE2/en/Operator_Overloading_(Delphi)
http://docwiki.embarcadero.com/RADStudio/en/Operator_Overloading_(Delphi) - At least 1 operand must be of the same type as your record data type:
– for single operand operators, the operand must be of the record data type
– for double operand operators, one or two operands must be of the record data type - The result type of the operator may be anything (so for comparison and set operators they do not need to return Boolean. Beware your users likely expect Boolean though).
Combining the rules of operator and result types, you can do magical things like Dances with XML | Australian Delphi User Group Members.
Do not use Delphi 2006 with operator overloading
Delphi 2007 fixed a number of bugs including this one: Delphi 2006 wont allow const parameters of type record within record method? – Stack Overflow.
Watch the result type of comparison operators!
Tips:
- Some operators should be overloaded pair-wise
= and <>
shl and shr
< and >=
> and <=
dec and inc
+ and –
/ and *
div and mod - Prefer Explicit over Implicit operators
- Beware of the built-in type coercion (implicit operators)
- e.g
- Byte to Integer;
- Integer to Double;
- Variants from/to anything!
Table of operators
operator | # | usage | name | cagetory | * |
and | 2 | R := A and B; | BitwiseAnd | bit | |
not | 1 | R := not A; | //BitwiseNot | bit | glitch: does not exist! |
or | 2 | R := A or B; | BitwiseOr | bit | |
xor | 2 | R := A xor B; | BitwiseXor | bit | |
() cast | 1 | R := TValue(A); | Explicit | conversion | |
:= | 1 | R := A; | Implicit | conversion | |
operator | # | usage | name | category | * |
round | 1 | R := Round(A); | Round | function | |
trunc | 1 | R := Trunc(A); | Trunc | function | |
and | 2 | R := A and B; | LogicalAnd | logical | |
not | 1 | R := not A; | LogicalNot | logical | |
or | 2 | R := A or B; | LogicalOr | logical | |
xor | 2 | R := A xor B; | LogicalXor | logical | |
operator | # | usage | name | category | * |
+ | 2 | R := A + B; | Add | binary | |
/ | 2 | R := A / B; | Divide | binary | |
div | 2 | R := A div B; | IntDivide | binary | |
mod | 2 | R := A mod B; | Modulus | binary | |
* | 2 | R := A * B; | Multiply | binary | |
– | 2 | R := A – B; | Subtract | binary | |
operator | # | usage | name | category | * |
shl | 2 | R := A shl B; | LeftShift | binary | name is confusing |
shr | 2 | R := A shr B; | RightShift | binary | name is confusing |
– | 1 | R := -A; | Negative | binary | |
+ | 1 | R := +A; | Positive | binary | |
dec | 1 | Dec(A); | Dec | self | |
inc | 1 | Inc(A); | Inc | self | |
operator | # | usage | name | category | * |
= | 2 | R := A = B; | Equal | comparison | |
> | 2 | R := A > B; | GreaterThan | comparison | |
>= | 2 | R := A >= B; | GreaterThanOrEqual | comparison | |
< | 2 | R := A < B; | LessThan | comparison | |
<= | 2 | R := A <= B; | LessThanOrEqual | comparison | |
<> | 2 | R := A <> B; | NotEqual | comparison | |
operator | # | usage | name | category | * |
in | 2 | R := A in B; | In | set |
–jeroen