今天查帮助的时候偶然看到, 真是不错
Operator Overloading
This topic describes Delphi's operator methods and how to overload them.
About Operator Overloading
Delphi for .NET and Delphi for Win32 allow certain functions, or "operators" to be overloaded within record declarations. Delphi for .NET also allows overloading within class declarations. The name of the operator function maps to a symbolic representation in source code. For example, the Add operator maps to the + symbol. The compiler generates a call to the appropriate overload, matching the context (i.e. the return type, and type of parameters used in the call), to the signature of the operator function. The following table shows the Delphi operators that can be overloaded:
Operator Category Declaration Signature Symbol Mapping
Implicit
Conversion
Implicit(a : type) : resultType;
implicit typecast
Explicit
Conversion
Explicit(a: type) : resultType;
explicit typecast
Negative
Unary
Negative(a: type) : resultType;
-
Positive
Unary
Positive(a: type): resultType;
+
Inc
Unary
Inc(a: type) : resultType;
Inc
Dec
Unary
Dec(a: type): resultType
Dec
LogicalNot
Unary
LogicalNot(a: type): resultType;
not
BitwiseNot
Unary
BitwiseNot(a: type): resultType;
not
Trunc
Unary
Trunc(a: type): resultType;
Trunc
Round
Unary
Round(a: type): resultType;
Round
Equal
Comparison
Equal(a: type; b: type) : Boolean;
=
NotEqual
Comparison
NotEqual(a: type; b: type): Boolean;
<>
GreaterThan
Comparison
GreaterThan(a: type; b: type) Boolean;
>
GreaterThanOrEqual
Comparison
GreaterThanOrEqual(a: type; b: type): resultType;
>=
LessThan
Comparison
LessThan(a: type; b: type): resultType;
<
LessThanOrEqual
Comparison
LessThanOrEqual(a: type; b: type): resultType;
<=
Add
Binary
Add(a: type; b: type): resultType;
+
Subtract
Binary
Subtract(a: type; b: type) : resultType;
-
Multiply
Binary
Multiply(a: type; b: type) : resultType;
*
Divide
Binary
Divide(a: type; b: type) : resultType;
/
IntDivide
Binary
IntDivide(a: type; b: type): resultType;
div
Modulus
Binary
Modulus(a: type; b: type): resultType;
mod
ShiftLeft
Binary
ShiftLeft(a: type; b: type): resultType;
shl
ShiftRight
Binary
ShiftRight(a: type; b: type): resultType;
shr
LogicalAnd
Binary
LogicalAnd(a: type; b: type): resultType;
and
LogicalOr
Binary
LogicalOr(a: type; b: type): resultType;
or
LogicalXor
Binary
LogicalXor(a: type; b: type): resultType;
xor
BitwiseAnd
Binary
BitwiseAnd(a: type; b: type): resultType;
and
BitwiseOr
Binary
BitwiseOr(a: type; b: type): resultType;
or
BitwiseXor
Binary
BitwiseXor(a: type; b: type): resultType;
xor
No operators other than those listed in the table may be defined on a class or record.
Overloaded operator methods cannot be referred to by name in source code. To access a specific operator method of a specific class or record, you must use explicit typecasts on all of the operands. Operator identifiers are not included in the class or record's list of members.
No assumptions are made regarding the distributive or commutative properties of the operation. For binary operators, the first parameter is always the left operand, and the second parameter is always the right operand. Associativity is assumed to be left-to-right in the absence of explicit parentheses.
Resolution of operator methods is done over the union of accessible operators of the types used in the operation (note this includes inherited operators). For an operation involving two different types A and B, if type A has an implicit conversion to B, and B has an implicit conversion to A, an ambiguity will occur. Implicit conversions should be provided only where absolutely necessary, and reflexivity should be avoided. It is best to let type B implicitly convert itself to type A, and let type A have no knowledge of type B (or vice versa).
As a general rule, operators should not modify their operands. Instead, return a new value, constructed by performing the operation on the parameters.
Overloaded operators are used most often in records (i.e. value types). Very few classes in the .NET framework have overloaded operators, but most value types do.
Declaring Operator Overloads
Operator overloads are declared within classes or records, with the following syntax:
type
typeName = [class | record]
class operator conversionOp(a: type): resultType;
class operator unaryOp(a: type): resultType;
class operator comparisonOp(a: type; b: type): Boolean;
class operator binaryOp(a: type; b: type): resultType;
end;
Implementation of overloaded operators must also include the class operator syntax:
class operator typeName.conversionOp(a: type): resultType;
class operator typeName.unaryOp(a: type): resultType;
class operator typeName.comparisonOp(a: type; b: type): Boolean;
class operator typeName.binaryOp(a: type; b: type): resultType;
The following are some examples of overloaded operators:
type
TMyClass = class
class operator Add(a, b: TMyClass): TMyClass; // Addition of two operands of type TMyClass
class operator Subtract(a, b: TMyClass): TMyclass; // Subtraction of type TMyClass
class operator Implicit(a: Integer): TMyClass; // Implicit conversion of an Integer to type TMyClass
class operator Implicit(a: TMyClass): Integer; // Implicit conversion of TMyClass to Integer
class operator Explicit(a: Double): TMyClass; // Explicit conversion of a Double to TMyClass
end;
// Example implementation of Add
class operator TMyClass.Add(a, b: TMyClass): TMyClass;
begin
// ...
end;
var
x, y: TMyClass;
begin
x := 12; // Implicit conversion from an Integer
y := x + x; // Calls TMyClass.Add(a, b: TMyClass): TMyClass
b := b + 100; // Calls TMyClass.Add(b, TMyClass.Implicit(100))
end;