Ada包体不编译

时间:2016-10-20 00:20:41

标签: packages ada

 package Bird_Package is 

    type Bird_Type is tagged private;

    procedure  Init(A_Bird : out Bird_Type; Name : in String);

    function   Name(A_Bird : in Bird_Type) return String;

    function   Call(A_Bird : in Bird_Type) return String;

    function   Type_Name(A_Bird : in Bird_Type) return String;

    procedure  Put(A_Bird : in Bird_Type);

 private

    type Bird_Type is tagged record
    My_Name : String (1..6);
     end record;
 end Bird_Package;

Package Body Bird_Package is


procedure Init(A_Bird: out Bird_Type; Name : in String) is
begin
     A_Bird.My_Name := Name;
 end Init;


 function Name(A_Bird : in Bird_Type) return String is 
 begin
    return A_Bird.A_Name;
 end Name;


 function Call(A_Bird : in Bird_Type) return String is
   begin
    return "Squawwwwwwk!";
 end Call;


function Type_Name(A_Bird : in Bird_Type) return String is
 begin
    return "Bird";
 end Type_Name;

procedure Put(A_Bird : in Bird_Type'Class) is
begin
        Put( Name(A_Bird) );
    Put( ' ' );
    Put( Type_Name(A_Bird) );
    Put( " says " );
    Put( Call(A_Bird) );
  end Put;
  end Bird_Package;

我的包体有问题我不明白Bird_Type' Class是什么,所以我不知道如何在我的客户端程序中应用它。它一直告诉我,期望的类型是Bird_Type' Class,但它找到的类型是Standard String。感谢帮助,谢谢

2 个答案:

答案 0 :(得分:2)

似乎你已经设置了一个课堂作业问题来修复一些低质量的代码(或者可能是故意的......)。如果在设置涉及它的问题之前没有人教你’Class,那么你应该挣扎是不足为奇的。

Bird_Type已被标记,因此可能意图是应该存在源自Bird_TypeParrotGoose,...)的子类型,并且应该适当地覆盖子程序(Parrot可能仍然会调用“Squawwwwwk!”,但Goose会“鸣喇叭”;因此Goose会覆盖Call,但Parrot将继承自Bird_Type)。

现在,您需要Put来调用正确的Call,这正是procedure Put(A_Bird : in Bird_Type’Class)所做的; A_Bird参数是Bird_Type或从中派生的某种类型(例如Goose),对Call的调用将调度到相应的子程序。

但是你给出的规范并没有使用classwide参数,所以如果你只是写

procedure Put(A_Bird : in Bird_Type) is
begin
   Put( Name(A_Bird) );
   Put( ' ' );
   Put( Type_Name(A_Bird) );
   Put( " says " );
   Put( Call(A_Bird) );
end Put;

然后说到最后一行,它能看到的唯一类型是Bird_Type,所以它只是“Squawwwwk!”无论。

但规范说您必须提供Put此参数配置文件。

在正文中有两个Put版本,一个采用类型为Bird_Type的参数,另一个采用Bird_Type’Class类型的参数。您可以尝试实现规范Put之类的

procedure Put (A_Bird : in Bird_Type) is
begin
   Put (Bird_Type'Class (A_Bird));
end Put;

现有Put之后使用classwide参数);但不幸的是,这导致了歧义,

$ gnatmake bird_package.adb
gcc -c bird_package.adb
bird_package.adb:43:07: ambiguous expression (cannot resolve "Put")
bird_package.adb:43:07: possible interpretation at bird_package.ads:13
bird_package.adb:43:07: possible interpretation at line 30
gnatmake: "bird_package.adb" compilation error

可以通过

修复
procedure Put (A_Bird : in Bird_Type) is
   procedure Classwide_Put (A_Bird : in Bird_Type'Class)
     renames Put;
begin
   Classwide_Put (Bird_Type'Class (A_Bird));
end Put;

但是,所有人都说,这个问题的正确方法是改变规范Put以获取全范围的参数!

答案 1 :(得分:0)

with Ada.Text_Io; use Ada.Text_IO;
Package Body Bird_Package is


   procedure Init(A_Bird: out Bird_Type; Name : in String) is
   begin
      A_Bird.My_Name := Name;
   end Init;


   function Name(A_Bird : in Bird_Type) return String is 
   begin
      return A_Bird.My_Name;
   end Name;


   function Call(A_Bird : in Bird_Type) return String is
   begin
      return "Squawwwwwwk!";
   end Call;


   function Type_Name(A_Bird : in Bird_Type) return String is
   begin
      return "Bird";
   end Type_Name;

   procedure Put(A_Bird : in Bird_Type) is
   begin
      Put( Name(A_Bird) );
      Put( ' ' );
      Put( Type_Name(A_Bird) );
      Put( " says " );
      Put( Call(A_Bird) );
   end Put;
 end Bird_Package;