我对Ada有相当多的经验,但我之前从未使用过对象。我发现我必须使用它们来避免非空访问的复杂性区分具有任务安全数据结构的记录类型。我需要创建一个接受基类并基于if语句执行动态调度的函数,但是我得到了一个"不兼容的类型"如果我正在测试的类型不在条件中的类中,则会出错。我想在Ada做不到的事吗?
with Ada.Text_IO; use Ada.Text_IO;
procedure Dispatch is
type foo is tagged record
bar : boolean;
end record;
type foo2 is new foo with record
bar2 : boolean;
end record;
type foo3 is new foo with record
bar3 : boolean;
end record;
f3 : foo3;
procedure Do_Something(fubar : in out foo'class) is
begin
if fubar in foo2'class then
fubar.bar2 := True;
end if;
end Do_Something;
begin
Do_Something(f3);
end Dispatch;
答案 0 :(得分:3)
此处,您的代码无法使用dispatch.adb:16:15: no selector “bar2" for type “foo'class" defined at line 3
进行编译;没有关于不兼容的类型。
无论如何,发布的代码问题是bar2
中没有组件foo
;通过类型foo’class
的视图在对象中可见的唯一组件是foo
类型的对象中的组件。
要解决此问题,您可以将fubar
的视图更改为foo2
:
if fubar in foo2'class then
foo2 (fubar).bar2 := true;
end if;
然而,这是不调度!要获得调度电话,您需要
并且您需要一个更复杂的示例,因为您只能在包规范中声明基本操作。像
这样的东西package Dispatch is
type Foo is tagged record
Bar : Boolean;
end record;
procedure Update (F : in out Foo; B : Boolean) is null; -- primitive
type Foo2 is new Foo with record
Bar2 : Boolean;
end record;
overriding procedure Update (F : in out Foo2; B : Boolean);
type Foo3 is new Foo with record
Bar3 : Boolean;
end record; -- inherits default Update
end Dispatch;
package body Dispatch is
procedure Update (F : in out Foo2; B : Boolean) is
begin
F.Bar2 := B;
end Update;
end Dispatch;
procedure Dispatch.Main is
F3 : Foo3;
procedure Do_Something(Fubar : in out Foo'Class) is
begin
Fubar.Update (True); -- dispatches
end Do_Something;
begin
Do_Something(F3);
end Dispatch.Main;