Operator Overloading i Delphi

Tags:    delphi
Skrevet af Bruger #782 @ 21.06.2007

Formål


Formålet med denne artikel er at udbredde forståelsen af Delphi's implementation af Operator Overloading[OO].
Jeg vil primært forholde mig til Win32 OO, som blev indført i år 2005. Det vil for de fleste nok kun være interresant hvis du har fået Turbo Delphi Explorer.

Det kræves i denne artikel at du ved hvordan man definerer en record.

Operator Overloading


OO kan for Win32 compileren kun foregå med records.
OO kan benyttes i mange situationer, men de steder hvor det er mest nærtliggende, er steder hvor man har interesse i, at programmere en løsning af et matematisk problem, der involverer vektorer eller andre matricer f.eks.

Jeg vil nu definere en vektor klasse:
Fold kodeboks ind/udKode 

Hvis man tidligere ville udføre aritmetiske operationer med en bunke af sådan nogle vektorer, så skulle man have en masse funktionskald.
Jeg kan hurtigt definere et par stykker, men jeg vil ikke kommentere yderligere på denne kode da den kun er her for at vise princippet:
Fold kodeboks ind/udKode 


Kikker vi på en operation, der matematisk ville defineres som (a+b)*(a-b) hvor a og b er to vektorer så vil man med den traditionelle fremgangsmåde i Delphi skulle skrive:
Fold kodeboks ind/udKode 

Dette kan man sikkert nok leve med men det ser ikke synderlig godt ud. Og ved større operationer kan det godt blive svært at finde rundt i.

Vi definerer derfor nogle nye operatorere!
Vi skal have fat i vores grunddefinition af TVector igen nu. Der er i Delphi et nyt keyword der hedder operator. Dette bruges til definitionen af en operator. Nedenfor er vist en simpel udvidelse af vores vektor:
Fold kodeboks ind/udKode 

Der findes en lang række operatorere du kan definere men du kan ikke definere nye som man kan i C++. Du kan for eksempel ikke redefinere hvordan ^ virker. Du kan se listen i sidste afsnit

For at udvide TVector klassen så alle de nødvendige operatorere bliver defineret så definerer vi lige operatorere for +,-,*
Fold kodeboks ind/udKode 


Med dette gjort kan vi nu compile og køre følgende kode f.eks:
Fold kodeboks ind/udKode 

Afslutning


Jeg håber dette har givet en forståelse for operator overloading i Delphi. Det er klart at man kan bruge disse til at lette ens arbejde en del på visse punkter, men når man kommer ud i at skulle kombinere operatorere på flere forskellige typer så kan man blive nød til at lave noget mindre flot kode for at kunne løse det.

Liste


Implicit
class operator Implicit(a : type) : resultType;
Denne operator skal bruges når man konverterer en type til en anden uden at bruge eksplicit typecast. Eksempel:
Fold kodeboks ind/udKode 


Explicit
class operator Explicit(a: type) : resultType;
Denne virker nogenlunde som Implicit bortset fra at du her skal lave en traditionel typecast. Eksempel:
Fold kodeboks ind/udKode 


Negative
class operator Negative(a: type) : resultType;
-

Positive
class operator Positive(a: type): resultType;
+

Inc
class operator Inc(a: type) : resultType;
Inc

Dec
class operator Dec(a: type): resultType
Dec

LogicalNot
class operator LogicalNot(a: type): resultType;
not

BitwiseNot
class operator BitwiseNot(a: type): resultType;
not

Trunc
class operator Trunc(a: type): resultType;
Trunc

Round
class operator Round(a: type): resultType;
Round

Equal
class operator Equal(a: type; b: type) : Boolean;
=

NotEqual
class operator NotEqual(a: type; b: type): Boolean;
<>

GreaterThan
class operator GreaterThan(a: type; b: type) Boolean;
>

GreaterThanOrEqual
class operator GreaterThanOrEqual(a: type; b: type): resultType;
>=

LessThan
class operator LessThan(a: type; b: type): resultType;
<

LessThanOrEqual
class operator LessThanOrEqual(a: type; b: type): resultType;
<=

Add
class operator Add(a: type; b: type): resultType;
+

Subtract
class operator Subtract(a: type; b: type) : resultType;
-

Multiply
class operator Multiply(a: type; b: type) : resultType;
*

Divide
class operator Divide(a: type; b: type) : resultType;
/

IntDivide
class operator IntDivide(a: type; b: type): resultType;
div

Modulus
class operator Modulus(a: type; b: type): resultType;
mod

ShiftLeft
class operator ShiftLeft(a: type; b: type): resultType;
shl

ShiftRight
class operator ShiftRight(a: type; b: type): resultType;
shr

LogicalAnd
class operator LogicalAnd(a: type; b: type): resultType;
and

LogicalOr
class operator LogicalOr(a: type; b: type): resultType;
or

LogicalXor
class operator LogicalXor(a: type; b: type): resultType;
xor

BitwiseAnd
class operator BitwiseAnd(a: type; b: type): resultType;
and

BitwiseOr
class operator BitwiseOr(a: type; b: type): resultType;
or

BitwiseXor
class operator BitwiseXor(a: type; b: type): resultType;
xor

Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.

Del også gerne artiklen med dine Facebook venner:  

Kommentarer (7)

User
Bruger #5097 @ 24.06.07 15:10
Syntes det er en utrolig dårlig forklaring af hvad artiklen handler om. Man får ikke at vide hvad det er, og hvad det kan bruges tid - og sår står man hurtigt af når man vil læse artiklen.
User
Bruger #782 @ 24.06.07 17:07
Det er jeg naturligvis ked af at du synes. Jeg skrev artiklen da jeg syntes det var utrolig svært at finde ud af hvordan delphi's operator overloading virkede. Operator overloading er ikke nogen ny teknik(i andet end Delphi) og det virkede naturligt for mig ikke at forklare det på tidspunktet.
User
Bruger #5097 @ 25.06.07 14:52
Hm hvad er gør teknikken så?
User
Bruger #782 @ 25.06.07 17:48
Redefinerer(overloader) den måde som de aritmetiske og boolske operatorere fungerer for visse kombinationer af typer.
User
Bruger #12143 @ 12.07.07 19:57
Kanon, vidste ikke det var kommet med Turbo, så er der da endeligt noget godt ved den opgradering.
User
Bruger #8985 @ 25.07.07 00:51
Navnet siger vel også lidt sig selv. En programmør bør vide, hvad en operator er, og det er da stortset almen viden, hvad det vil sige at 'overloade'.
User
Bruger #13703 @ 05.05.08 10:22
hvor fedt!
Jeg anede ikke at Delphi understøttede operator overload. Har ofte savnet det, især ifm. vektorer naturligvis.

Det er jo så lidt ærgeligt at det kun fungerer på records, men det er da en start.
Du skal være logget ind for at skrive en kommentar.
t