zoukankan      html  css  js  c++  java
  • 运算符重载

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

  • 相关阅读:
    spring mvc给参数起别名
    聊聊分布式定时任务中间件架构及其实现--转
    Batch Normalization的算法本质是在网络每一层的输入前增加一层BN层(也即归一化层),对数据进行归一化处理,然后再进入网络下一层,但是BN并不是简单的对数据进行求归一化,而是引入了两个参数λ和β去进行数据重构
    终端安全工具 gartner 排名
    When Cyber Security Meets Machine Learning 机器学习 安全分析 对于安全领域的总结很有用 看未来演进方向
    DNS隧道之DNS2TCP实现——dns2tcpc必须带server IP才可以,此外ssh可以穿过墙的,设置代理上网
    DNS隧道之DNS2TCP使用心得教程——是可以用来穿透qiang的,ubuntu下直接apt install dns2tcp
    DNS隧道工具汇总——补充,还有IP over DNS的工具NSTX、Iodine、DNSCat
    Data Mining and Machine Learning in Cybersecurity PDF
    ES failed to notify ClusterStateListener java.lang.IllegalStateException: environment is not locked
  • 原文地址:https://www.cnblogs.com/huking/p/1790314.html
Copyright © 2011-2022 走看看