在 Ada 中使用访问类型进行动态调度 [英] Dynamic Dispatching in Ada with Access Types

查看:78
本文介绍了在 Ada 中使用访问类型进行动态调度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个使用访问类型进行动态调度的包.我已经使用 This Q/A 作为指南使用类类型实现了动态调度.

I am trying to create a package that has Dynamic dispatching using access types. I have achieved Dynamic Dispatching using Class Types using This Q/A as a guide.

我不断收到编译错误,提示:无法调用抽象子程序.这让我认为编译器要么不识别专用子程序,要么不将该类型识别为专用类型.但我觉得两者都对……我不明白.

I keep getting a compilation error that says: cannot call abstract subprogram. This makes me think that the compiler either doesnt recognize the specialized subprogram, or doesnt recognize the type as a specialized type. But both seem right to me... I dont get it.

ma​​in.2.ada

with Ada.Text_IO;
with Animal.Cat;

procedure Main is
    Tabby        : aliased Animal.Cat.Cat_t;
    Animal_Ref   : Animal.Any_Animal_Ptr := Tabby'Unchecked_Access;
    Result       : Boolean;
begin
    Animal.Stroke_Fur (Animal => Animal_Ref.all);

    Result := Animal.Is_Happy(Ptr => Animal_Ref);

    Ada.Text_IO.Put_Line ("Happy Animal = " & Boolean'Image (Result));

end Main;

animal.1.ada

package Animal is

    type base_t is abstract tagged limited null record;

    type Animal_t is abstract new 
        base_t with private;

    type Any_Animal_Ptr is access all Animal_t'Class;
    ----
    procedure Stroke_Fur (Animal : in out Animal_t) is abstract;
    ----
    function Is_Happy (Ptr : in Any_Animal_Ptr) return boolean is abstract;

private

    type Animal_t is abstract new base_t with 
    record
        Index : integer;
    end record;

end Animal;

animal.cat.1.ada

package Animal.Cat is

    type Cat_t is new Animal.Animal_t with private;
    type Cat_Ptr is access all Cat_t;

    ----
    procedure Stroke_Fur (Cat : in out Cat_t);
    ----
    function Is_Happy (Ptr : in Cat_Ptr) return Boolean;

private
    type Cat_t is new Animal.Animal_t with 
    record
        Purr : Boolean := False;
    end record;            

end Animal.Cat;

animal.cat.2.ada

package body Animal.Cat is

    ----
    procedure Stroke_Fur (Cat : in out Cat_t) is
    begin
        Cat.Purr := True;
    end Stroke_Fur;
    ----
    function Is_Happy (Ptr : in Cat_Ptr) return Boolean is
    begin
        return Ptr.Purr;
    end Is_Happy;

end Animal.Cat;

错误

main.2.ada:13:21:不能调用抽象子程序Is_Happy"

推荐答案

function Is_Happy (Ptr : in Any_Animal_Ptr) return boolean is abstract;

不是原始操作(ARM3.2.3(2)),所以它没有调度;它只是一个抽象的子程序(因此不能被调用).

isn’t a primitive operation (ARM3.2.3(2)) of Animal_t, and so it isn’t dispatching; it’s merely an abstract subprogram (which therefore can’t be called).

为什么要将非调度子程序抽象化?也许你有一个 Metres 类型,在这种情况下,预定义的 "*" 是不合适的(以米为单位的两个距离相乘返回一个区域,而不是一个距离),你可能想要使其抽象以防止无意中误用.

Why would you want to make a non-dispatching subprogram abstract? Perhaps you might have a type Metres, in which case the predefined "*" is inappropriate (multiplying two distances in metres returns an area, not a distance) and you might want to make it abstract to prevent inadvertent misuse.

无论如何,您可以使用访问为

Anyway, you can declare a primitive operation of Animal_t using accesses as

function Is_Happy (Ptr : access Animal_t) return boolean is abstract;

然后是猫

function Is_Happy (Ptr : access Cat_t) return Boolean;

(甚至

overriding
function Is_Happy (Ptr : access Cat_t) return Boolean;

如果您希望编译器检查它是否确实被覆盖).

if you want the compiler to check that it really is overriding).

顺便说一下,如果您使用的是 Ada 2005 或更高版本,则可以使用 前缀符号 将调用写为

By the way, if you are using Ada 2005 or later you can use the prefixed notation to write the calls as

Animal_Ref.Stroke_Fur;
Result := Animal_Ref.Is_Happy;

哪个更漂亮.

这篇关于在 Ada 中使用访问类型进行动态调度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆