2016-10-20 55 views
1
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,但它找到的類型是標準字符串。幫助表示讚賞,謝謝Ada包體不編譯

+0

是否有一個程序或功能,我可以添加到修復身體,所以它會工作? –

+0

您似乎想要使用Ada.Text_IO中的Put過程,但是沒有上下文子句指出對Ada.Text_IO的依賴關係。在Put過程中,您在傳遞一個字符串時調用Put,但包中唯一的Put過程是您使用Bird_Type'Class的參數定義的Put過程。順便說一下,Put包體中的參數爲Bird_Type'Class,而包中的Put爲一個Bird_Type類型。它們不是同一件事。 Bird_Type'Class是以Bird_Type爲根的任何類型,或從Bird_Type繼承的類型。 –

+0

這是它給我的方式,我必須保持Bird_Type在規範中,而Bird_Type'Class在身體中。我需要在程序和函數中進行編譯,但是我不知道如何執行 –

回答

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; 
+0

軟件包中仍存在運行時問題。 Bird_Type.My_Name字段被定義爲String(1..6),這意味着它只能包含6個字符。 Procedure Init包含String類型的第二個參數,它可以是任何大小的字符串。當您嘗試爲不完全6個字符長的鳥分配名稱時,會發生運行時錯誤。你應該考慮如何避免這個問題。 –

2

看來你已經設置了一個課堂問題來修復一些低質量的代碼(或者可能它的目的很棘手......)。如果沒有人在設置涉及它的問題之前教過你關於’Class的信息,那麼你應該更換它並不奇怪。

Bird_Type被標記,所以推測其意圖是,應該有來自Bird_TypeParrotGoose ...)派生子類型,並且應該適當地覆蓋子程序(一Parrot可能仍稱之爲「Squawwwwwk!」但Goose將「Honk」;因此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採取classwide參數!