2012-04-07 16 views
2

這是我的問題here的後續。根據Ada中的關鍵字創建對象並調用其方法

我已經到了程序中的一個地步,我覺得我不能再繼續使用當前的結構,所以我做了很多重寫。 Statement類型不再抽象,並且每個Statement的子類型創建它自己的Statement的變量實例。我還從Statements包中刪除了摘要execute函數,因爲編譯器不喜歡這種情況(每個子類型仍然有它自己的execute方法)。 execute函數已被更改爲過程,因爲必須修改傳入的Statement類型。我將statementFactory(以前稱爲createStatement)移動到Statement包。

這是我得到的錯誤:

statements-compoundstatements.adb:15:29: expected type "CompoundStatement" defined at statements-compoundstatements.ads:11 
statements-compoundstatements.adb:15:29: found type "Statement'Class" defined at statements.ads:6 

我在阿達一個初學者,但我的直覺是,因爲execute程序是CompoundStatements(這是一個「繼承」報表)它將永遠無法看到語句的另一個「子類」的execute方法。我能想到的唯一解決方案是將所有execute程序轉儲到Statement程序包中,但這似乎不合要求。但是這仍然不能解釋爲什麼stmt.all被用作Statement'Class的類型,而不是statementFactory中創建的類型。

這是新代碼:

package Statements is 

    type Statement is tagged private; 

    type Statement_Access is access all Statement'Class; 
    ParserException : Exception; 

    procedure createStatement(tokens : Vector; S : out Statement); 
    procedure statementFactory(S: in out Statement; stmt: out Statement_Access); 

--.....A bunch of other procedures and functions..... 

private 
    type Statement is tagged 
     record 
     tokens : Vector; 
     executedtokens : Vector; 
     end record; 

end Statements; 

procedure createStatement(tokens : Vector; S : out Statement) is 
    begin 
     S.tokens := tokens; 
    end createStatement; 

    procedure statementFactory(S: in out Statement; stmt: out Statement_Access) is 
     currenttoken : Unbounded_String; 
     C   : CompoundStatement; 
     A   : AssignmentStatement; 
     P   : PrintStatement; 

    begin 
     currenttoken := getCurrentToken(S); 
     if currenttoken = "begin" then 
     createStatement(S.tokens, C); 
     stmt := new CompoundStatement; 
     stmt.all := Statement'Class(C); 
     elsif isVariable(To_String(currenttoken)) then 
     createStatement(S.tokens, A); 
     stmt := new AssignmentStatement; 
     stmt.all := Statement'Class(A); 
     elsif currenttoken = "print" then 
     createStatement(S.tokens, P); 
     stmt := new PrintStatement; 
     stmt.all := Statement'Class(P); 
    end statementFactory; 

package body Statements.CompoundStatements is 

    procedure execute(skip: in Boolean; C: in out CompoundStatement; reset: out Integer) is 
     stmt: Statement_Access; 
     tokensexecuted: Integer; 
     currenttoken : Unbounded_String; 
    begin 
     match(C, "begin"); 
     currenttoken := getCurrentToken(C); 
     while(currenttoken /= "end") loop 
     statementFactory(C, stmt); 
     execute(skip, stmt.all, tokensexecuted); //ERROR OCCURS HERE 

回答

5

你說「我也刪除了抽象從報表包的執行功能,因爲編譯器不喜歡那」;但你真的需要它,否則編譯器如何知道當你撥打execute (skip, stmt.all, tokensexecuted)時,任何stmt.all都會提供一個execute來分配給它?

擴展類型不僅繼承了其父類型的屬性(因此每個CompoundStatement等已經有tokensexecutedtokens),它繼承了父類的基元操作;如果父操作是abstract,那麼孩子必須提供它自己的實現,如果不是,那麼孩子可以提供它自己的(重寫)實現。

請參閱Ada 95 RationaleWikibooks對此進行良好的討論。

+0

好吧,我加回到'procedure execute(skip:in Boolean; S:in out Statement; reset:out Integer)是抽象的;'但編譯器仍抱怨說'Statement'不是抽象的,但是我早些時候已經提交了這個摘要,編譯器也不喜歡這個。原來我也忽略了也做'陳述'摘要的記錄。這似乎解決了這個問題。在一個問題上花費數小時,結果變得非常簡單。再次感謝你。 – 2012-04-07 12:50:47

+0

我已經在這個項目上花費了數週的時間,並且在星期一到期,但即使我沒有完全使用它,我感覺我已經瞭解了很多關於Ada和我以前不知道的編碼。此外,我現在對Ada的瞭解比以前好多了,所以我只討厭Ada。 :) – 2012-04-07 12:52:29

+0

希望事情順利! – 2012-04-07 13:26:29

相關問題