博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ADA程序实例(运算符重载)
阅读量:5142 次
发布时间:2019-06-13

本文共 6433 字,大约阅读时间需要 21 分钟。

ADA支持对几乎它自身的所有运算符的重载,虽然ADA的运算符系统不像C/C++那样庞大灵活,ADA提供这种重载某种意义上说是为了达到作为对象操作的一致性要求,这也理应是运算符重载的目的。由于ADA本身的运算符定义特征,所有运算符都是单目或双目的,而ADA将他们均看成函数(function),其参数是输入性(in)对象类型,输出是这种对象类型。以下是一般用来阐释运算符重载的经典方法之一,复数的定义和运算。其实ADA本身也提供了复数的泛型模板,但是这里的小例子强调一些ADA的语言特征。比如ADA本身提供的复数泛型只支持数值类型作为复数分量,而这里采用了任何类型。

复数定义文件(complex.ads),这里几点注意:

ADA的泛型参数约束比较复杂,但是个人认为基本上是靠谱的,比PASCAL的类型相容性定义不知要好了多少了。因为它基本描述了ADA中允许的数据定义的种类。这里用了is private,大体上是支持几乎所有的ADA数据类型,关于这些泛型参数约束的说明可参见。由于类型约束很松,所以在泛型参数里还要加上对这个类型用到的运算和方法的指定。在这里是一组运算符(加减乘除和负号)以及一个转换到字符串的函数。这些运算符显然在复数运算中要用到。有意思的是,由于减号和负号的符号是一致的,作为泛型的形参的时候(见在后面complex.adb中实例化)会发生二义性(虽然理论上编译器可以通过函数参数来分辨这个重载,但可能ADA的设计不允许代码中出现这种含糊的情况),所以这里只能用实名函数来代替,随后再用ADA一个很有意思也很强大的renaming特性将他们转化成为运算符,供这个泛型模板的实现中继续用运算符的方式使用它们。这里可见在ADA中,在运算符重载意义上,运算符和函数是没有区别的。

generic    -- the type of the components of the complex number is defined here  -- as genereic argument delcared as 'private' which basically can   -- be almost any ADA type  type value_t is private;    -- since value_t is declared as 'private', the caller needs to explicitly  -- provide operators on the type used by this program even if the actual   -- type is numerics.  -- since subtract and minus operations share the same symbol, we might have  -- to use named function for formal arguments here to differentiate them,   -- fortunately we can use ADA's renaming feature to switch them back.  with function "+" (x, y : value_t) return value_t;  with function subtract (x, y : value_t) return value_t;  with function "*" (x, y : value_t) return value_t;  with function "/" (x, y : value_t) return value_t;  with function minus(x : value_t) return value_t;    -- function to convert the value to string  with function to_string(x : value_t) return string;  package complex is  -- renaming for subtract and minus operations  function "-"(x, y : value_t) return value_t renames subtract;  function "-"(x: value_t) return value_t renames minus;    -- declaration of the complex object type in the public region  type object is tagged private;    -- set individual component of a complex  procedure set_real(obj : in out object; r : value_t);  procedure set_imag(obj : in out object; i : value_t);    -- get individual component of a complex  function get_real(obj : in object) return value_t;  function get_imag(obj : in object) return value_t;    -- operator overloading for complex objects    function "+"(obj1, obj2 : in object) return object;  function "-"(obj1, obj2 : in object) return object;  function "*"(obj1, obj2 : in object) return object;  function "/"(obj1, obj2 : in object) return object;  function "-"(obj : in object) return object;    -- cast to and from string   function to_string(obj : in object) return string;  private    -- detailed data definition for complex object  type object is tagged record    r : value_t;    i : value_t;  end record;  end complex;

Note that I later realized that the operator as formal generic parameter can be specified in a different way (less ugly than having function-like names) to either

1. look for and make use of existing operators defined on the respective type without having to specify what and where they are (as long as the operator definitions end with box "is <>" which indicates use of default) 

2. use => symbol to explicitly associate formal parameters and actual parameters excluding ambiguous formal parameters (e.g., "-" operators above, o.w., an error saying "name not allowed for overloaded operators" will be given)

3. pass the parameters in the same order as the corresponding formal parameters are defined.

复数的实现文件(complex.adb),从这里可见对分量类型的所有运算符都配置好了,所有只要用加加减减就能成了。
with Ada.Strings.Fixed; use Ada.Strings.Fixed;package body complex is    -- setters and getters    procedure set_real(obj : in out object; r : value_t) is  begin    obj.r := r;  end set_real;    procedure set_imag(obj : in out object; i : value_t) is  begin    obj.i := i;  end set_imag;    function get_real(obj : in object) return value_t is  begin    return obj.r;  end get_real;    function get_imag(obj : in object) return value_t is  begin    return obj.i;  end get_imag;      -- operator overloading for complex objects      function "+"(obj1, obj2 : in object) return object is    result : object;  begin    result.r := obj1.r + obj2.r;    result.i := obj1.i + obj2.i;    return result;  end "+";    function "-"(obj1, obj2 : in object) return object is    result : object;  begin    result.r := obj1.r - obj2.r;    result.i := obj1.i - obj2.i;    return result;  end "-";    function "*"(obj1, obj2 : in object) return object is    result : object;  begin    result.r := obj1.r * obj2.r - obj1.i * obj2.i;    result.i := obj1.r * obj2.i + obj1.i * obj2.r;    return result;  end "*";    function "/"(obj1, obj2 : in object) return object is    q : value_t;    result : object;  begin    q := obj2.r * obj2.r + obj2.i * obj2.i;    result.r := (obj1.r * obj2.r + obj1.i * obj2.i) / q;    result.i := (obj1.r * obj2.i - obj1.i * obj2.r) / q;    return result;  end "/";    function "-"(obj : in object) return object is    result : object;  begin    result.r := -obj.r;    result.i := -obj.i;    return result;  end "-";  -- conversion from complex object to the string that represents it  function to_string(obj : in object) return string is    result_str : string(1..32) := 32 * " ";  begin    result_str := overwrite(result_str, 1,                             to_string(obj.r) & to_string(obj.i) & 'j');    return result_str;  end;    end complex;

示例主程序(operatorsdemo.adb),在这里的泛型模板的实例化中要对这些形参赋予实际的内容,可见这里的运算符实参就是float运算符本身,(目前为止至少没有发现)而这些运算符估计是系统内建而不依赖于任何package的。

with Ada.Text_IO; use Ada.Text_IO;with Ada.Strings.Fixed; use Ada.Strings.Fixed;use Ada.Strings;with complex;procedure operatorsdemo is    function float_to_string(value : float) return string is  begin    return Trim(float'Image(value), Both);  end float_to_string;      package float_complex is new complex(value_t=>float, "+"=>"+",                                        subtract=>"-", minus=>"-",                                       "*"=>"*", "/"=>"/",                                        to_string=>float_to_string);  use float_complex;    c1, c2, c : float_complex.object;   begin  Put_Line("Operators Overloading Demo");    c1.set_real(3.0);  c1.set_imag(4.0);  c2.set_real(5.0);  c2.set_imag(6.0);    c := c1 * (-c2);    Put("c = c1 * c2 = ");  Put_Line(c.to_string);  end operatorsdemo;

转载于:https://www.cnblogs.com/quanben/archive/2011/11/19/3128880.html

你可能感兴趣的文章
android linux环境搭建
查看>>
P3868 [TJOI2009]猜数字
查看>>
二级证丢失如何找回
查看>>
Hiberante链接查询的
查看>>
[Leetcode]81. Search in Rotated Sorted Array II
查看>>
ROS kinect 语音
查看>>
利用kubeadm部署k8s
查看>>
如何在MVC中显示条形码图片(以内存流的方式)
查看>>
解析文件夹下的所有二维码,并输出二维码中的信息
查看>>
高精度加减
查看>>
表单验证
查看>>
python细节2
查看>>
游戏引擎 Unity 的入门易精通难体现在哪?为什么?
查看>>
爬虫几大框架解读
查看>>
仿饿了么收藏功能
查看>>
2018.2.5 PHP如何写好一个程序用框架
查看>>
Django如何用真实的IP访问
查看>>
用标签、按钮和文本框编辑一个个人信息简介页面
查看>>
SQL查询xml内容
查看>>
根据URL提取页面的Title,根据网页的charset自动判断Encoding
查看>>