我有以下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个过程的签名是什么样的?
答案 0 :(得分:3)
当类型T具有原始子程序,并且您说“类型T2是新T”或“类型T2是带有...的新T”时,将隐式声明新的子程序。在新的子程序中,如果任何参数类型为T
或access T
,则它将替换为T2
或access T2
;如果它是返回类型为T
或access 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;
M1
和M2
的声明在首次声明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;
M1
和M2
的声明在首次声明W
时不可见,因为尚未看到它们。因此,他们不在那时继承。但是,当看到完整类型时,隐式声明将在稍后继承。但是,这些隐式声明位于private
的{{1}}部分;因此,它们可以直接调用(即不通过调度)只能在程序中可以看到P
的{{1}}部分,即private
的主体并在适当的位置调用子代码包P
。