首页 文章

动态调度

提问于
浏览
0

我对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 回答

  • 3

    在这里,您的代码无法使用 dispatch.adb:16:15: no selector “bar2" for type “foo'class" defined at line 3 进行编译;没有关于不兼容的类型 .

    无论如何,发布的代码问题是 foo 中没有组件 bar2 ;通过类型 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;
    

相关问题