动态调度

时间:2014-07-23 07:04:39

标签: ada

我对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;

1 个答案:

答案 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;

然而,这是调度!要获得调度电话,您需要

  • 基本类型中的基本操作(此处无)
  • 一个类范围的对象或指针(OK)

并且您需要一个更复杂的示例,因为您只能在包规范中声明基本操作。像

这样的东西
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;