Delphi documentation says that it is possible to overload the Inc and Dec operators; I see no valid way to do it. Here are attempts to overload the Inc operator; some attempts lead to compile errors, some to runtime access violation (Delphi XE):
program OverloadInc;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TMyInt = record
FValue: Integer;
// class operator Inc(var A: TMyInt); DCC error E2023
class operator Inc(var A: TMyInt): TMyInt;
property Value: Integer read FValue write FValue;
end;
class operator TMyInt.Inc(var A: TMyInt): TMyInt;
begin
Inc(A.FValue);
Result:= A;
end;
type
TMyInt2 = record
FValue: Integer;
class operator Inc(A: TMyInt2): TMyInt2;
property Value: Integer read FValue write FValue;
end;
class operator TMyInt2.Inc(A: TMyInt2): TMyInt2;
begin
Result.FValue:= A.FValue + 1;
end;
procedure Test;
var
A: TMyInt;
begin
A.FValue:= 0;
Inc(A);
Writeln(A.FValue);
end;
procedure Test2;
var
A: TMyInt2;
I: Integer;
begin
A.FValue:= 0;
// A:= Inc(A); DCC error E2010
Writeln(A.FValue);
end;
begin
try
Test; // access violation
// Test2;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
To overload an operator, we use a special operator function. We define the function inside the class or structure whose objects/variables we want the overloaded operator to work with.
It is not possible to change the precedence, grouping, or number of operands of operators. The overload of operator -> must either return a raw pointer, or return an object (by reference or by value) for which operator -> is in turn overloaded.
To work, at least one of the operands must be a user-defined class object. We can only overload the existing operators, Can't overload new operators. Some operators cannot be overloaded using a friend function. However, such operators can be overloaded using the member function.
Operators Overloading in C++ Overloaded operators are functions with special names: the keyword "operator" followed by the symbol for the operator being defined.
The signature of the operator is wrong. It should be:
class operator Inc(const A: TMyInt): TMyInt;
or
class operator Inc(A: TMyInt): TMyInt;
You cannot use a var
parameter.
This program
{$APPTYPE CONSOLE}
type
TMyInt = record
FValue: Integer;
class operator Inc(const A: TMyInt): TMyInt;
property Value: Integer read FValue write FValue;
end;
class operator TMyInt.Inc(const A: TMyInt): TMyInt;
begin
Result.FValue := A.FValue + 1;
end;
procedure Test;
var
A: TMyInt;
begin
A.FValue := 0;
Inc(A);
Writeln(A.FValue);
end;
begin
Test;
Readln;
end.
produces this output:
1
Discussion
This is a rather unusual operator when overloaded. In terms of usage the operator is an in-place mutation. However, when overloaded, it works like an addition operator with an implicit addend of one.
So, in the code above this line:
Inc(A);
is effectively transformed into
A := TMyInt.Inc(A);
and then compiled.
If you are wanting to maintain true in-place mutation semantics, and avoid the copying associated with this operator, then I believe that you need to use a method of the type.
procedure Inc; inline;
....
procedure TMyInt.Inc;
begin
inc(FValue);
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With