Ada派生类型和原始操作

时间:2014-01-30 04:10:20

标签: ada

我有以下Ada代码。

type U i s tagged private ;
type W i s new U with private ;
type X i s new W with private ;

procedure m1 (P1 : U; P2 : in out U; P3 : Integer ) ;
procedure m2 (P1 : Float ; P2 : in out U) ;
procedure m2 (P1 : Float ; P2 : Boolean ; P3 : in out W) ;

不是我不明白派生类型中的这些操作会发生什么。 我认为这三个程序都是原始操作。

但派生类型中程序的签名是什么。

可能是这个

procedure m1 (P1 : W; P2 : in out U; P3 : Integer ) ;
procedure m2 (P1 : Float ; P2 : in out W) ;
procedure m2 (P1 : Float ; P2 : Boolean ; P3 : in out X) ;

或者在派生类型中这3个过程的签名是什么样的?

1 个答案:

答案 0 :(得分:3)

当类型T具有原始子程序,并且您说“类型T2是新T”或“类型T2是带有...的新T”时,将隐式声明新的子程序。在新的子程序中,如果任何参数类型为Taccess T,则它将替换为T2access T2;如果它是返回类型为Taccess T的函数,则类似地替换返回类型。

如果没有涉及private类型或扩展,则新子程序将在派生类型之后隐式声明。 E.g:

type U is tagged null record ;
procedure m1 (P1 : U; P2 : in out U; P3 : Integer ) ;
procedure m2 (P1 : Float ; P2 : in out U) ;

type W is new U with null record ;
-- procedure m1 (P1 : W; P2 : in out W; P3 : Integer ) ; --implicitly declared
-- procedure m2 (P1 : Float ; P2 : in out W) ; --implicitly declared
procedure m2 (P1 : Float ; P2 : Boolean ; P3 : in out W);
    -- this last is a *new* procedure.  It doesn't override the other m2 because
    -- it has a new Boolean parameter.  Instead, it's an example of *overloading*.

-- So now W has three primitive operations, two that were inherited and one that
-- is brand new.

type X is new W with null record ;
-- procedure m1 (P1 : X; P2 : in out X; P3 : Integer ) ; --implicitly declared
-- procedure m2 (P1 : Float ; P2 : in out X) ; --implicitly declared
-- procedure m2 (P1 : Float ; P2 : Boolean ; P3 : in out X); --implicitly declared

-- All three of W's primitive operations, including the implicitly declared ones,
-- are inherited for X.

with private并没有太大改变,只是它改变了声明隐式子程序的点。我相信它们是在完整类型定义之后声明的,它将在您的包的私有部分中。这意味着除了在程序中可以看到包的私有部分的位置之外,它们不可见。 (但是,它们可能仍会被调度操作调用。)

编辑:对于with private案例,继承的子程序的可见性由RM 7.3.1(7)决定:

  

对于private_extension_declaration,如果来自祖先的相应声明在该位置可见,则在private_extension_declaration之后立即声明每个继承的子程序。否则,未为私有扩展声明继承的子程序,尽管它可能是完整类型。

因此:

package P is

    type U is tagged private;
    procedure M1 (P1 : U; P2 : in out U; P3 : Integer);
    procedure M2 (P1 : Float ; P2 : in out U);

    type W is new U with private;
    --procedure M1 (P1 : W; P2 : in out W; P3 : Integer); -- implicitly declared
    --procedure M2 (P1 : Float ; P2 : in out W); -- implicitly declared

private
    type U is ... -- full type definition
    type W is new U with ...  -- full type definition
end P;

M1M2的声明在首次声明W的位置可见;因此他们在那时继承了。由于这一点属于P的公共部分,因此任何包含with P的包都可以引用它们。但是:

package P is

    type U is tagged private;

    type W is new U with private;

    procedure M1 (P1 : U; P2 : in out U; P3 : Integer);
    procedure M2 (P1 : Float ; P2 : in out U);

private
    type U is ... -- full type definition
    type W is new U with ...  -- full type definition
    --procedure M1 (P1 : W; P2 : in out W; P3 : Integer); -- implicitly declared
    --procedure M2 (P1 : Float ; P2 : in out W); -- implicitly declared
end P;

M1M2的声明在首次声明W可见,因为尚未看到它们。因此,他们在那时继承。但是,当看到完整类型时,隐式声明将在稍后继承。但是,这些隐式声明位于private的{​​{1}}部分;因此,它们可以直接调用(即不通过调度)只能在程序中可以看到P的{​​{1}}部分,即private的主体并在适当的位置调用子代码包P