艾达:了解私有类型并了解包装 [英] Ada: Understanding private types and understanding packaging

查看:93
本文介绍了艾达:了解私有类型并了解包装的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试学习如何在Ada中使用私有声明,以及如何理解包装.我试图使代码尽量简短.

我们从主文件rectangular_Form.ads

开始

with Rectangular_Method_1;
package Rectangular_Form renames Rectangular_Method_1;
-- with Rectangular_Method_2;
-- package Rectangular_Form renames Rectangular_Method_2;

这告诉我们可以有两个实现,并且目前已经选择了Rectangular_Method_1.

然后我们有了规格文件Rectangular_Method_1.ads:

package Rectangular_Method_1 is
   type Rectangular is private;

   procedure Vector_Basis_r (A : in Long_Float; D : out Rectangular);
   procedure Set_Horz (R : in out Rectangular; H : Long_Float);
   function Get_Horz (R : Rectangular) return Long_Float;

 private
   type Rectangular is
        record
             Horz, Vert: Long_Float;
        end record;
end Rectangular_Method_1;

及其主体Rectangular_Method_1.adb:

with Ada.Numerics.Long_Elementary_Functions;
use  Ada.Numerics.Long_Elementary_Functions;

package body Rectangular_Method_1 is
procedure Vector_Basis_r (A : in Long_Float; D : out Rectangular) is
begin
  D.Horz := Cos (A, Cycle => 360.0);
  D.Vert := Sin (A, Cycle => 360.0);
end Vector_Basis_r;

procedure Set_Horz (R : in out Rectangular; H : Long_Float) is
begin
  R.Horz := H;
end Set_Horz;

function Get_Horz (R : Rectangular) return Long_Float is
begin
  return R.Horz;
end Get_Horz;

end Rectangular_Method_1;

最后是测试脚本:test_rectangular_form.adb:

with Ada.Long_Float_Text_IO;
with Ada.Text_IO; use Ada.Text_IO;
with Rectangular_Form;
use type Rectangular_Form.Rectangular;

procedure Test_Rectangular_Form is
Component_Horz, Component_Vert, Theta  : Long_Float;
Basis_r                                : Rectangular_Form.Rectangular;

begin
  Ada.Text_IO.Put("Enter the angle ");
  Ada.Long_Float_Text_IO.Get (Item => theta);

  --Vector basis
  Rectangular_Form.Vector_Basis_r (A => Theta, D => Basis_r);
  Ada.Text_IO.New_Line;

  Ada.Text_IO.Put("rhat_min_theta = ");
  Ada.Long_Float_Text_IO.Put (Item => Rectangular_Form.Get_Horz (Basis_r), Fore => 3, Aft  => 5, Exp  => 0);
  Ada.Text_IO.Put(" ihat + ");
  Ada.Long_Float_Text_IO.Put (Item => Rectangular_Form.Get_Vert (Basis_r), Fore => 3, Aft  => 5, Exp  => 0);
  Ada.Text_IO.Put (" jhat ");
end Test_Rectangular_Form;

问题(适用于test_rectangular_form.adb):

我正在直接使用

    Rectangular_Form.Get_Vert (Basis_r)

A.Vert组件

    Rectangular_Form.Vector_Basis_r (A => Theta, D => Basis_r);

并稍后通过仅使用

访问水平和垂直组件

    Rectangular_Form.Get_Horz (Basis_r)

    Rectangular_Form.Get_Vert (Basis_r)

这似乎不错,因为我正在使用方法Get_HorzGet_Vert来访问 private Rectangular 水平和垂直组件.但是我直接从命令行读取变量Theta,并使用

查找其水平和垂直分量

    Rectangular_Form.Vector_Basis_r (A => Theta, D => Basis_r);

如果按照我的定义,矩形组件A.HorzA.Vert是私有的,为什么我不必先使用方法set_Horz(A)set_Vert(A) 发出命令

    Rectangular_Form.Vector_Basis_r (A => Theta, D => Basis_r);

PS:省略了Set_VertGet_Vert的功能,以使代码简短.

非常感谢...

解决方案

为什么我不必事先使用set_Horz(A)和set_Vert(A)方法 发出命令

因为要通过执行以下操作设置您的私人记录字段:

Rectangular_Form.Vector_Basis_r(A => Theta,D => Basis_r);

(查看Vector_Basis_r的实现.)

-扩展答案

在Test_Rectangular_Form过程中声明Basis_r变量时,将为该矩形"变量分配内存.此时,存在私有类型的Horz和Vert字段,但是未设置(它们可以包含任何内容).

调用Rectangular_Form.Vector_Basis_r时,其实现会设置这些私有字段的值.也许这就是让您感到困惑的地方:声明了私有类型的程序包主体可以直接访问那些字段.这正是Vector_Basis_r在设置其值(以及Set_Vert和Set_Horz)时所利用的方面.

I am trying to learn how to use private declarations in Ada and also to understand packaging. I have tried to keep my codes as short as possible.

We start with the main file rectangular_Form.ads

with Rectangular_Method_1;
package Rectangular_Form renames Rectangular_Method_1;
-- with Rectangular_Method_2;
-- package Rectangular_Form renames Rectangular_Method_2;

This tells us that we can have two implementations and that for now Rectangular_Method_1 has been chosen.

Then we have the specifications file Rectangular_Method_1.ads:

package Rectangular_Method_1 is
   type Rectangular is private;

   procedure Vector_Basis_r (A : in Long_Float; D : out Rectangular);
   procedure Set_Horz (R : in out Rectangular; H : Long_Float);
   function Get_Horz (R : Rectangular) return Long_Float;

 private
   type Rectangular is
        record
             Horz, Vert: Long_Float;
        end record;
end Rectangular_Method_1;

and its body Rectangular_Method_1.adb:

with Ada.Numerics.Long_Elementary_Functions;
use  Ada.Numerics.Long_Elementary_Functions;

package body Rectangular_Method_1 is
procedure Vector_Basis_r (A : in Long_Float; D : out Rectangular) is
begin
  D.Horz := Cos (A, Cycle => 360.0);
  D.Vert := Sin (A, Cycle => 360.0);
end Vector_Basis_r;

procedure Set_Horz (R : in out Rectangular; H : Long_Float) is
begin
  R.Horz := H;
end Set_Horz;

function Get_Horz (R : Rectangular) return Long_Float is
begin
  return R.Horz;
end Get_Horz;

end Rectangular_Method_1;

and finally the test script: test_rectangular_form.adb:

with Ada.Long_Float_Text_IO;
with Ada.Text_IO; use Ada.Text_IO;
with Rectangular_Form;
use type Rectangular_Form.Rectangular;

procedure Test_Rectangular_Form is
Component_Horz, Component_Vert, Theta  : Long_Float;
Basis_r                                : Rectangular_Form.Rectangular;

begin
  Ada.Text_IO.Put("Enter the angle ");
  Ada.Long_Float_Text_IO.Get (Item => theta);

  --Vector basis
  Rectangular_Form.Vector_Basis_r (A => Theta, D => Basis_r);
  Ada.Text_IO.New_Line;

  Ada.Text_IO.Put("rhat_min_theta = ");
  Ada.Long_Float_Text_IO.Put (Item => Rectangular_Form.Get_Horz (Basis_r), Fore => 3, Aft  => 5, Exp  => 0);
  Ada.Text_IO.Put(" ihat + ");
  Ada.Long_Float_Text_IO.Put (Item => Rectangular_Form.Get_Vert (Basis_r), Fore => 3, Aft  => 5, Exp  => 0);
  Ada.Text_IO.Put (" jhat ");
end Test_Rectangular_Form;

Question (applied to test_rectangular_form.adb):

I am getting the components A.Horz and A.Vert directly using

    Rectangular_Form.Vector_Basis_r (A => Theta, D => Basis_r);

and accessing the horizontal and vertical components later on by just using

    Rectangular_Form.Get_Horz (Basis_r)

and

    Rectangular_Form.Get_Vert (Basis_r)

This seems OK as I am using the methods Get_Horz and Get_Vert to access the private Rectangular horizontal and vertical components. However I am reading the variable Theta directly from the command line and finding its horizontal and vertical components using

    Rectangular_Form.Vector_Basis_r (A => Theta, D => Basis_r);

If the Rectangular components A.Horz and A.Vert are private as I have defined them, why do not I have to use the methods set_Horz(A) and set_Vert(A) prior to issuing the command

    Rectangular_Form.Vector_Basis_r (A => Theta, D => Basis_r);

PS: The functions for Set_Vert and Get_Vert were omitted to keep the codes short.

Thanks a lot...

解决方案

why do not I have to use the methods set_Horz(A) and set_Vert(A) prior to issuing the command

Because you're setting the fields of your private record by executing:

Rectangular_Form.Vector_Basis_r (A => Theta, D => Basis_r);

(Review the implementation of Vector_Basis_r.)

-- EXPANDED Answer

When you declare the Basis_r variable in your Test_Rectangular_Form procedure, the memory for that "Rectangular" variable is allocated. At this point the Horz and Vert fields in the private type are present, but unset (they could contain anything).

When you call Rectangular_Form.Vector_Basis_r, its implementation sets the values of those private fields. Maybe this is what's confusing you: the body of the package in which a private type is declared has direct access to those fields. This is exactly the aspect that Vector_Basis_r is exploiting when setting their values (as well as Set_Vert and Set_Horz).

这篇关于艾达:了解私有类型并了解包装的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆