【发布时间】:2016-03-11 06:00:05
【问题描述】:
我正在尝试创建一个使用访问类型进行动态调度的包。我以This Q/A 为指导,使用类类型实现了动态调度。
我不断收到一个编译错误:无法调用抽象子程序。这让我觉得编译器要么不识别专门的子程序,要么不将类型识别为专门的类型。但在我看来,两者都是正确的……我不明白。
main.2.ada
with Ada.Text_IO;
with Animal.Cat;
procedure Main is
Tabby : aliased Animal.Cat.Cat_t;
Animal_Ref : Animal.Any_Animal_Ptr := Tabby'Unchecked_Access;
Result : Boolean;
begin
Animal.Stroke_Fur (Animal => Animal_Ref.all);
Result := Animal.Is_Happy(Ptr => Animal_Ref);
Ada.Text_IO.Put_Line ("Happy Animal = " & Boolean'Image (Result));
end Main;
animal.1.ada
package Animal is
type base_t is abstract tagged limited null record;
type Animal_t is abstract new
base_t with private;
type Any_Animal_Ptr is access all Animal_t'Class;
----
procedure Stroke_Fur (Animal : in out Animal_t) is abstract;
----
function Is_Happy (Ptr : in Any_Animal_Ptr) return boolean is abstract;
private
type Animal_t is abstract new base_t with
record
Index : integer;
end record;
end Animal;
animal.cat.1.ada
package Animal.Cat is
type Cat_t is new Animal.Animal_t with private;
type Cat_Ptr is access all Cat_t;
----
procedure Stroke_Fur (Cat : in out Cat_t);
----
function Is_Happy (Ptr : in Cat_Ptr) return Boolean;
private
type Cat_t is new Animal.Animal_t with
record
Purr : Boolean := False;
end record;
end Animal.Cat;
animal.cat.2.ada
package body Animal.Cat is
----
procedure Stroke_Fur (Cat : in out Cat_t) is
begin
Cat.Purr := True;
end Stroke_Fur;
----
function Is_Happy (Ptr : in Cat_Ptr) return Boolean is
begin
return Ptr.Purr;
end Is_Happy;
end Animal.Cat;
错误
main.2.ada:13:21:无法调用抽象子程序“Is_Happy”
【问题讨论】:
-
您为什么使用访问类型以及动态调度?如果您只尝试动态调度,这可能会更容易。
-
@JacobSparreAndersen - 我使用访问类型是因为在我的实际代码中,我使用的是相当大的对象,这不是我可以改变的事实。我宁愿明确地使用指针,也不愿希望优化器为我这样做。我以为我在我的方法
Stroke_Fur中使用了动态调度,并且它起作用了。你能澄清你为什么问这个问题吗?听起来你在推断两者应该是互斥的,但我不太确定你的意思。 -
大多数 Ada 程序员已经开始依赖他们的编译器供应商来避免生成效率极低的代码。参数模式表示意图;对于
access,您不太确定传递的对象会发生什么。无论如何,标记的类型都是通过引用 (AARM05 6.2)。 -
@Jerunh 我问是因为使用访问类型是一种不必要的复杂性,它可能会隐藏您对标记类型的实际挑战。 (正如 Simon 所写,标记类型是按引用传递的类型,因此优化器对它们如何作为参数传递没有任何发言权。)
标签: dynamic polymorphism ada