3

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...

4

1 回答 1

4

为什么我不必在发出命令之前使用方法 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)时所利用的方面。

于 2012-05-01T14:58:35.583 回答