【问题标题】:Ada derived types and primitive operationAda 派生类型和原始操作
【发布时间】:2014-01-31 07:55:35
【问题描述】:

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

不是我不明白派生类型中的这种操作会发生什么。 我认为这 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 个过程的签名是什么样的?

【问题讨论】:

    标签: ada


    【解决方案1】:

    当一个类型 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 并没有太大的改变,只是它改变了隐式子程序的声明点。我相信它们是在 full 类型定义之后声明的,这将在您的包的私有部分中。这意味着它们不可见,除非在程序中可以看到包的私有部分的地方。 (但是,它们仍可能被调度操作调用。)

    编辑: 对于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 部分;因此,它们只能在可以看到Pprivate 部分的程序部分中直接调用(即不能通过调度),即P 的主体和P 的子包中的适当位置.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多