zoukankan      html  css  js  c++  java
  • [转]Delphi的运算符重载

    使用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++要方便,因为你不用考虑内存释放;也可以不用定义构造函数。

  • 相关阅读:
    python基础-------模块与包(一)
    python基础-------函数(三)
    python基础-------函数(二)
    python基础-------函数(一)
    python基础(三)----字符编码以及文件处理
    python基础(二)-------数据类型
    python基础(一)------Python基础语法与介绍
    linux进程、软件包的安装和删除,及安装python3.6(源代码方式)
    Linux磁盘分区、打包压缩、软硬链接练习
    linux关于目录或文件权限的练习
  • 原文地址:https://www.cnblogs.com/moon25/p/2072211.html
Copyright © 2011-2022 走看看