Delphi的運算子多載

來源:互聯網
上載者:User

使用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++要方便,因為你不用考慮記憶體釋放;也可以不用定義建構函式。
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.