代码之家  ›  专栏  ›  技术社区  ›  Dan

实现类似于ADA95接口的东西的最佳方法是什么?

  •  0
  • Dan  · 技术社区  · 6 年前

    我想实现类似于使用ADA95的接口的东西(因此典型的OO接口不可用)。我通过在一个记录中使用泛型和一组“指向方法的指针”来完成这项工作。代码如下。

    编辑: 我知道可以通过将子程序作为形式参数传递给通用包来实现,但我希望避免向它传递太多参数。

    我认为必须有更好的方法来实现我想要的东西,所以如果我是对的,我希望看到代码的一个例子。

    “interface”在一个名为 Drivers .在这里,有一个记录用来包含表示驱动程序的通用类型变量和包含其操作的记录:

    司机.ads

    generic 
        type T is private;
        type Error is private;
        NOT_IMPLEMENTED_CODE : Error;
    
    package Drivers is
    
        type Driver is private;
    
        -- Need to declare these types because I compile with Ada 95.
        type ToStringPtr is access function(self : in T) return String;
        type ReadLinePtr is access procedure(self : in T; buffer : out String; err : out Error);
    
        type DriverOps is
        record
            to_string_op : ToStringPtr := null;
            read_line_op : ReadLinePtr := null;
        end record;
    
        function create_driver(underlying : T; ops : DriverOps) return Driver;
    
        function to_string(self : in Driver) return String;
    
        procedure read_line(self : in Driver; buffer : out String; err : out Error);
    
    
        private
            type Driver is
            record
                underlying : T;
                ops : DriverOps;
            end record;
    
    end Drivers;
    

    驱动程序.adb

    package body Drivers is
    
        function create_driver(underlying : T; ops : DriverOps) return Driver is
        begin
            return (underlying, ops);
        end create_driver;
    
        function to_string(self : in Driver) return String is
        begin
            if self.ops.to_string_op /= null then
                return self.ops.to_string_op(self.underlying);
            else
                return "";
            end if;
        end to_string;
    
        procedure read_line(self : in Driver; buffer : out String; err : out Error) is
        begin
            if self.ops.read_line_op /= null then
                self.ops.read_line_op(self.underlying, buffer, err);
            else
                err := NOT_IMPLEMENTED_CODE;
            end if;
        end read_line;
    
    end Drivers;
    

    主要.adb

    with Ada.Text_IO; use Ada.Text_IO;
    with Ada.Strings.Fixed; 
    
    with Drivers;
    
    procedure main is
    
        type Error is (SUCCESS, NOT_IMPLEMENTED, UNKNOWN);
    
        type MyInt is new Integer;
    
        function to_string(self : in MyInt) return String is
        begin
            return Integer'Image( Integer(self) ); --'
        end to_string;
    
        procedure read_line(self : in MyInt; buffer : out String; err : out Error) is
        begin
            Ada.Strings.Fixed.Move(
                Target => buffer,
                Source => "Lets suppose we have read this from a device" & ASCII.LF,
                Pad => ASCII.NUL); 
            err := SUCCESS;
        end read_line;
    
    
        package IntDrivers is new Drivers(MyInt, Error, NOT_IMPLEMENTED);
        use IntDrivers;
    
    
        underlying : MyInt := 25;
    
        int_driver_ops : DriverOps := (
            to_string_op => to_string'access, --'
            read_line_op => read_line'access  --'
        );
    
        my_driver : Driver := create_driver(underlying, int_driver_ops);
        buffer : String(1..256) := (others => Character'Val(0)); --'
        err : Error := SUCCESS;
    begin
        Put_Line(to_string(my_driver));
    
        read_line(my_driver, buffer, err);
        Put(buffer);
        Put_Line(Error'Image(err)); --'
    end main;
    
    2 回复  |  直到 6 年前
        1
  •  5
  •   Simon Wright    6 年前

    我只知道下面描述的一个,可能不是

    简而言之:

    type InterfaceX is abstract ....; -- abstract class and services
    
    type ClassA is tagged ...; -- or is new ....
    type Trick (component : ClassA) is new InterfaceX ...; -- this type gives you access to classA and interfaceX primitives
    

    您必须定义类对象或技巧对象的instantiaton/访问器。我认为类型也应该受到限制。

    也许你会在这里找到更精确的答案 http://www.adaic.org/resources/add_content/standards/95rat/rat95html/rat95-p2-4.html#6

        2
  •  4
  •   Jacob Sparre Andersen    6 年前

    abstract tagged null record 在ADA 95中:

    package Abstract_Driver is
    
       type Instance is abstract tagged null record;
       subtype Class is Instance'Class; --' (defect syntax highlighter)
    
       function Image (Item : in Instance) return String is abstract;
    
       procedure Read_Line (Item   : in out Instance;
                            Buffer :    out String) is abstract;
    
    end Abstract_Driver;
    
    with Abstract_Driver;
    
    package Text_IO_Driver is
    
       subtype Parent is Abstract_Driver.Instance;
       type Instance is new Parent with private;
       subtype Class is Instance'Class; --' (defect syntax highlighter)
    
       function Image (Item : in Instance) return String;
    
       Buffer_Too_Small : exception;
    
       procedure Read_Line (Item   : in out Instance;
                            Buffer :    out String);
    
    private
    
       type Instance is new Parent with null record;
    
    end Text_IO_Driver;
    
    with Ada.Text_IO;
    
    package body Text_IO_Driver is
    
       function Image (Item : in Instance) return String is
       begin
          return "Ada.Text_IO.Standard_Input";
       end Image;
    
       procedure Read_Line (Item   : in out Instance;
                            Buffer :    out String) is
          Last : Natural;
       begin
          Buffer := (Buffer'Range => ' '); --' (defect syntax highlighter)
          Ada.Text_IO.Get_Line (Item => Buffer,
                                Last => Last);
          if Last = Buffer'Last then --' (defect syntax highlighter)
             raise Buffer_Too_Small;
          end if;
       end Read_Line;
    
    end Text_IO_Driver;