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。感谢帮助,谢谢
答案 0 :(得分:2)
似乎你已经设置了一个课堂作业问题来修复一些低质量的代码(或者可能是故意的......)。如果在设置涉及它的问题之前没有人教你’Class
,那么你应该挣扎是不足为奇的。
Bird_Type
已被标记,因此可能意图是应该存在源自Bird_Type
(Parrot
,Goose
,...)的子类型,并且应该适当地覆盖子程序(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;