2014-01-30 82 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的兒童包裝中的適當位置的程序的部分中直接調用它們(即,不通過調度)。