2014-01-30 49 views
1

我有以下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) ; 

不是我不明白,在派生类型此操作excatly发生。 我认为3个程序是原始操作。

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

难道这

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个程序?

回答

3

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

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

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首先声明,因为它们还没有被见过的点可见。因此,他们而不是在那一点上继承。但隐式声明稍后会被继承,当看到完整类型时。但是,这些隐式声明位于Pprivate部分;因此,只能在可看到P的部分P,即P的身体以及P的儿童包装中的适当位置的程序的部分中直接调用它们(即,不通过调度)。