使用Delphi編寫遊戲,唯一沒有C++方便的就是不支援運算子多載。當你編寫有關向量或者矩陣計算的程式時,不支援運算子多載的Delphi使用起來是很費勁的。
但是Delphi 2006改變了這種局面,新的Delphi核心已經支援運算子多載了!
本文將介紹如何使用Delphi的運算子多載功能
注意:只有Delphi 2006 和 免費版的 Turbo Delphi 支援這一功能!
Delphi for Win32 只支援 record 類型的運算子多載,而 Delphi .NET 還支援 class 類型的運算子多載
下面是Delphi支援的可重載運算子
運算子 類型 聲明文法 應用符號
Implicit 轉換 Implicit(a: type): resultType; 隱式轉換
Explicit 轉換 Explicit(a: type): resultType; 顯式轉換
負 一元運算 Negative(a: type): resultType; -
正 一元運算 Positive(a: type): resultType; +
遞增 一元運算 Inc(a: type): resultType; Inc
遞減 一元運算 Dec(a: type): resultType; Dec
邏輯非 一元運算 LogicalNot(a: type): resultType; not
按位非 一元運算 BitwiseNot(a: type): resultType; not
截取 一元運算 Trunc(a: type): resultType; Trunc
舍入 一元運算 Round(a: type): resultType; Round
等於 比較 Equal(a: type; b: type) : Boolean; =
不等於 比較 NotEqual(a: type; b: type): Boolean; <>
大於 比較 GreaterThan(a: type; b: type) Boolean; >
大於等於 比較 GreaterThanOrEqual(a: type; b: type): resultType;>=
小於 比較 LessThan(a: type; b: type): resultType; <
小於等於 比較 LessThanOrEqual(a: type; b: type): resultType; <=
加 二元運算 Add(a: type; b: type): resultType; +
減 二元運算 Subtract(a: type; b: type): resultType; -
乘 二元運算 Multiply(a: type; b: type): resultType; *
除 二元運算 Divide(a: type; b: type): resultType; /
整除 二元運算 IntDivide(a: type; b: type): resultType; div
模 二元運算 Modulus(a: type; b: type): resultType; mod
左移 二元運算 ShiftLeft(a: type; b: type): resultType; shl
右移 二元運算 ShiftRight(a: type; b: type): resultType; shr
邏輯與 二元運算 LogicalAnd(a: type; b: type): resultType; and
邏輯或 二元運算 LogicalOr(a: type; b: type): resultType; or
邏輯異或 二元運算 LogicalXor(a: type; b: type): resultType; xor
按位與 二元運算 BitwiseAnd(a: type; b: type): resultType; and
按位或 二元運算 BitwiseOr(a: type; b: type): resultType; or
按位異或 二元運算 BitwiseXor(a: type; b: type): resultType; xor
在具體介紹如何使用運算子多載前,我先說說Delphi裡record的新功能。
Delphi2006 裡,record已經和class 很類似了,例如
type
TMyRecord = record
private
x : Integer;
public
constructor Create(val : Integer);
procedure Change(arg : integer); overload;
procedure Change(arg1, arg2 : Integer);overload;
end;
record和class的區別是
record 不支援繼承
record 包含可變部分;class沒有(關於可變部分,請參考Delphi2006的協助檔案)
record 是實值型別;class是參考型別(具體的情況,同樣請參考Delphi2006的協助檔案)
record 允許在Win32 和 .Net平台都支援運算子多載;class只在.NET裡支援
record 是自動構造的,使用的是預設的無參數建構函式,class必須顯式構造;由於record擁有預設的無參數建構函式,所以使用者定義的建構函式至少要有一個參數
record 沒有解構函式
record 不支援虛方法
record 在Win32裡不支援interface的實現,在.NET裡可以支援
好了,該看看運算子多載是如何?的了
首先是定義,句法如下:
type
typeName = [class | record] //只有使用.NET時,才能用class
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;
實現部分的句法如下:
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;
還是看看具體的例子吧
type
TVector = record
x : Single;
y : Single;
z : Single;
public
constructor Create(x1, y1, z1); //這個建構函式可以不用寫,原因稍後告知
class operator Add(V1, V2 : TVector): TVector; //重載運算子 +
class operator Implicit(i : Single): TVector; overload; //隱式轉換
class operator Implicit(i : TVector): TVector; overload; //同上
end;
//具體的實現
{ TVector }
constructor TVector.Create(x1, y1, z1: Single);
begin
x := x1;
y := y1;
z := z1;
end;
class operator TVector.Add(V1, V2: TVector): TVector;
begin
Result.x := v1.x + v2.x;
Result.y := v1.y + v2.y;
Result.z := v1.z + v2.z;
Result.w := v1.w + v2.w;
end;
class operator TVector.Implicit(i: Single): TVector;
begin
Result.x := i;
Result.y := i;
Result.z := i;
Result.w := i;
end;
class operator TVector.Implicit(i: TVector): TVector;
begin
Result.x := i.x;
Result.y := i.y;
Result.z := i.z;
Result.w := i.w;
end;
//調用方法
...
var
v1, v2 : TVector;
begin
...
v1.Create(1, 2, 3);
//也可以用如下的方法給x,y,z賦值
// v1.x := 1;
// v1.y := 2;
// v1.z := 3;
//所以說剛才的Create函數可以不要
//和class不同,record可以自動給成員初始化
//這個例子裡,x,y,z的初始化值為 0
v2 := 1; //調用了class operator Implicit(i : TVector): TVector
//這時v2所有成員都被賦值成1
v2 := v1; //調用了class operator Implicit(i : TVector): TVector
v2 := v1 + v2; //調用了class operator Add(V1, V2 : TVector): TVector;
v2 := v2 + 1; // class operator Add(V1, V2 : TVector): TVector
//和class operator Implicit(i : TVector): TVector的複合調用
end;
Delphi的這種實現方式顯然比C++要方便,因為你不用考慮記憶體釋放;也可以不用定義建構函式。