Can I overload operators for my own classes in Delphi?
I faced a little trouble - I do not know if I can define my own operators for my classes. For example:
type TMinMatrix = class(TMatrix) private RowAmount: Byte; ColAmount: Byte; Data: DataMatrix; DemVector, SupVector: SupplyDemand; public constructor Create(Rows, Cols: Byte); function GetRowAmount: Byte; override; function GetColAmount: Byte; override; destructor Destroy; end;
How can I - or can`t I:) - do something like:
TMinMatrix TMinMatrix::operator=(TMinMatrix* matr) (c++ code)
And, by the way, can I define copy constructor for my class?
Operator overloading is possible in Delphi .NET versions, older versions of Delphi don't support it.
Delphi Win32 2007 and 2009 only supports class operator overload for records, you can have implicit and explicit operators. Delphi .Net supports class operators for records and classes.
The "traditional" method of copying classes in Delphi is by overriding the "AssignTo" method of TPersistant. This usually takes the form of
TSubclass(Dest).Field1 := Field1; TSubclass(Dest).Field2 := Field2;
Which is a bit of a pain.
a CreateCopy constructor would then call this method:
constructor CreateCopy(ASource : TMyClass); begin Create; Assign(ASource); // calls AssignTo end;
another trick in later (works in 2006) versions of Delphi is to use an record type to store the fields.
class TMyClass = class(TPersistent) protected type // 2005+ only, otherwise use standalone record TMyRecord = record Name : string; ID : integer; end; FData : TMyRecord; procedure AssignTo(Dest : TPersistent);override; public property Name : string read FData.Name; property ID: Integer read FData.ID; end; procedure TMyClass.AssignTo(Dest : TPersistent); begin if Dest is TMyClass then TMyClass(Dest).FData := FData else inherited; // raise EConvertError end;
This gets messy if you keep adding fields in sub-classes - need to add new record types, but it automatically handles new fields added into TMyrecord (don't have to remember to update AssignTo())
type TMinMatrix = class(TMatrix) public A : integer; class operator Add( ATM, BTM : TMinMatrix ) : TMinMatrix; // CTM := ATM + BTM class operator Subtract( ATM, BTM : TMinMatrix ) : TMinMatrix; // CTM := ATM - BTM; end; class operator TMinMatrix.Add( ATM, BTM : TMinMatrix ) : TMinMatrix; begin result := ATM.A + BTM.A; end; class operator TMinMatrix.Subtract( ATM, BTM : TMinMatrix ) : TMinMatrix; begin result := ATM.A - BTM.A; end; var A, B, C : TMinMatrix; begin C := A + B; // calls Add() C := B - A; // calls Subtract() end.
Other operators are:
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 LeftShift Binary LeftShift(a: type; b: type): resultType; shl RightShift Binary RightShift(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
Whatever Drejc and Cesar said + Delphi Win32 2007 and 2009 don't support copy constructors as far as I know (I'm 100% for D2007, not totally sure for D2009).
Operator overloading in Delphi Win32 works only for records, not for classes.
It works from Delphi 2006 and up, but there were some bugs fixed in Delphi 2007 that make them easier to work with (having to do with calling functions on operator results).
I gave a session on Record Operator Overloading on CodeRage 3; You can get the slides and sample code at 26326 CR3: Nullable Types w/ Records, Methods & Operator Overloading, and/or watch the video replay at DOWNLOAD VIDEO REPLAY.
This was the session abstract:
Nullable Types with Records, Methods and Operator Overloading One of the things where data from databases and Delphi native types differ, is the support for NULL. When you work with databases a lot in Delphi, you want to have a datatype that supports NULL. In the past you had to use variants, but not any more! With the introduction of operator overloading, you can do this with record types, too. This session shows you how.
The reason operator overloading is only possible for records in Delphi Win32 (i.e. non .NET), is that records are value types, so their memory management is non-dynamic. Classes are reference types, hence require dynamic memory allocation: they require the concept of a garbage collector in order for operators to work on them.
Since there is no concept of a garbage collector in Delphi Win32, it is not possible in to have operators for classes in Delphi Win32.
Note that CodeRage 4 starts next week. It has a nice line up of speakers and sessions.
I suppose copy constructor is an idiom, not a language feature. So I can do it like this: constructor CreateCopy(var t: MyType);
constructor MyType.CreateCopy(var t: MyType); begin //... end;
Delphi allows certain functions, or operators, to be overloaded within record declarations. You can see here: http://edn.embarcadero.com/article/34324