【问题标题】:Ada: How to override a subprogram of an interfaceAda:如何覆盖接口的子程序
【发布时间】:2021-05-31 06:33:57
【问题描述】:

在以下代码中:

with Ada.Text_IO;    use Ada.Text_IO;
with Ada.Containers; use Ada.Containers;
with Ada.Containers.Vectors;

procedure Main is

   package IEnumerators is
      -- An umbrella class for all things that are iterable
      type IEnumerator is interface;
      procedure Move_Next (Self : in out IEnumerator) is abstract;
   end IEnumerators;
   use IEnumerators;

   package IEnumerables is
      -- The iterator for IEnumerator
      type IEnumerable is interface;
      function Get_Enumerator
        (Self : IEnumerable) return IEnumerator is abstract;
   end IEnumerables;
   use IEnumerables;

   package Lists is
      -- An IEnumerable whose underlying is a vector

      package Integer_Vector is new Ada.Containers.Vectors
        (Element_Type => Integer, Index_Type => Positive, "=" => "=");

      -- FAIL: type must be declared abstract or "Get_Enumerator" overridden
      -- Fair enough, there's a problem with Get_Enumerator in the body
      type List is new IEnumerable with record
         Members : Integer_Vector.Vector;
      end record;
   end Lists;

   package body Lists is

      type List_Enumerator is new IEnumerator with null record;

      overriding procedure Move_Next (Self : in out List_Enumerator) is
      begin
         null; -- do something
      end Move_Next;

      overriding
         -- FAIL: subprogram "Get_Enumerator" is not overriding. 
         function Get_Enumerator (Self : List) return List_Enumerator
      is
         Result : List_Enumerator;
      begin
         return Result;
      end Get_Enumerator;
   end Lists;

begin
   null;
end Main;

我不明白为什么覆盖的 Get-Enumerator 会失败;它与包 IEnumerables 中的签名相同(List 是一个具体的 IEnumerable,List_Enumerator 是一个具体的 IEnumerator)。

我哪里出错了?

【问题讨论】:

    标签: inheritance interface overriding ada


    【解决方案1】:

    首先,编译器抱怨规范,因为你没有覆盖Get_Enumerator

    包列表是 -- 一个 IEnumerable,其底层是一个向量

      package Integer_Vector is new Ada.Containers.Vectors
        (Element_Type => Integer, Index_Type => Positive, "=" => "=");
    
      type List is new IEnumerable with record
         Members : Integer_Vector.Vector;
      end record;
    
      overriding
      function Get_Enumerator
        (Self : List) return IEnumerator;
    

    其次,编译器在正文中抱怨,因为覆盖必须在规范中(类型声明所在的位置),并且您也有错误的签名。 Ada 不支持协同推导:

      -- same signature as the parent
      -- overriding is usually not indicated in both spec and body
      function Get_Enumerator (Self : List) return IEnumerator
      is
         Result : List_Enumerator;
      begin
         return Result; -- now this won't compile, wrong type
      end Get_Enumerator;
    

    第三,你没有根据继承的签名返回正确的类型,就像我上面说的,Ada 不支持共同派生。但是,您可以告诉编译器您要返回 IEnumerator 或任何从 IEnumerator 派生的类型,如下所示:

    package IEnumerables is
       -- The iterator for IEnumerator
       type IEnumerable is interface;
       function Get_Enumerator
         (Self : IEnumerable) return IEnumerator'Class is abstract;
    end IEnumerables;
    

    以及Lists 规范中的覆盖:

      overriding
      function Get_Enumerator
        (Self : List) return IEnumerator'Class
    

    Lists正文:

      function Get_Enumerator (Self : List) return IEnumerator'Class
      is
         Result : List_Enumerator;
      begin
         return Result;
      end Get_Enumerator;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-31
      • 2020-03-06
      • 2012-11-10
      • 2016-12-09
      相关资源
      最近更新 更多