2012-08-27 88 views
1

我想了解標記的類型和代碼擴展和重用。我首先創建一個程序conventional_method_number_of_averages,它實現了一種計算方法。然後,我使用標記類型的擴展並創建第二個程序alternative_method_number_of_averages,它實現瞭解決同一問題的不同方法。所不同的是,現在我有一個額外的parameteroverlap_fraction。這是第一個方法conventional_method_number_of_averages工作正常的簡單程序:Ada:標記類型---從父包繼承

  1. number_of_averages.ads

    with Conventional_Method_Number_Of_Averages; 
    package Number_Of_Averages renames Conventional_Method_Number_Of_Averages; 
    
  2. conventional_method_number_of_averages.ads

    package Conventional_Method_Number_Of_Averages is 
    
    type First_Method is tagged private; 
    
    procedure Count_Averages (Any_Method : in out First_Method; Sampling_Frequency, FFT_Size, Time_Recorded: in Float); 
    
    function Average_Is (Any_Method : in First_Method) return Float; 
    
    private 
    type First_Method is tagged 
        record 
        Number_Of_Averages : Float :=0.0; 
        end record; 
    
    end Conventional_Method_Number_Of_Averages; 
    
  3. 約定al_method_number_of_averages.adb

    package body Conventional_Method_Number_Of_Averages is 
    
    procedure Count_Averages (Any_Method : in out First_Method; Sampling_Frequency, FFT_Size, Time_Recorded: in Float) is 
    begin 
        Any_Method.Number_Of_Averages := (((Sampling_Frequency * Time_Recorded) - FFT_Size)*(2.0/FFT_Size)) + 1.0; 
    end Count_Averages; 
    
    function Average_Is (Any_Method : in First_Method) return Float is 
    begin 
        return Any_Method.Number_Of_Averages; 
    end; 
    
    end Conventional_Method_Number_Of_Averages; 
    
  4. 和測試文件test_number_of_averages.adb

    with Ada.Float_Text_IO; 
    with Ada.Text_IO; use Ada.Text_IO; 
    
    with Number_Of_Averages; 
    with Conventional_Method_Number_Of_Averages; 
    use type Number_Of_Averages.First_Method; 
    procedure Test_Number_Of_Averages is 
    
    Fs, Time_Duration, NFFT : Float := 0.0; 
    Averages     : Float := 0.0; 
    
    Good_Method : Conventional_Method_Number_Of_Averages.First_Method; 
    
    begin 
        Ada.Text_IO.Put("Enter the sampling frequency "); 
        Ada.Float_Text_IO.Get (Item => Fs); 
        Ada.Text_IO.New_Line (1); 
        Ada.Text_IO.Put("Enter the time recorded "); 
        Ada.Float_Text_IO.Get (Item => Time_Duration); 
        Ada.Text_IO.New_Line (1); 
        Ada.Text_IO.Put("Enter the FFT size "); 
        Ada.Float_Text_IO.Get (Item => NFFT); 
        Ada.Text_IO.Put_Line (Ada.Text_IO.Get_Line); 
    
        Ada.Text_IO.New_Line(1); 
        Ada.Text_IO.Put("Number of averages = "); 
        Number_Of_Averages.Count_Averages(Good_Method, Fs, NFFT, Time_Duration); 
    
        Averages := Conventional_Method_Number_Of_Averages.Average_Is(Good_Method); 
        Ada.Float_Text_IO.Put (Item => Averages, Fore => 3, Aft => 5, Exp => 0); 
    
    end Test_Number_Of_Averages; 
    

以上工作正常,因爲它是。

現在,如果我創建相同的計算的另一種方法,我有:

  1. 其說明書alternative_method_number_of_averages.ads

    with Conventional_Method_Number_Of_Averages; 
    use Conventional_Method_Number_Of_Averages; 
    
    package Alternative_Method_Number_Of_Averages is 
    
    type Second_Method is new First_Method with private; 
    
    --override this function 
    procedure Count_Averages (Any_Method : in out Second_Method; Sampling_Frequency, FFT_Size, Time_Recorded, Overlap_Fraction: in Float); 
    
    
    private 
    type Second_Method is new First_Method with 
        record 
        Overlap_Fraction : Float :=0.5; 
        end record; 
    
    end Alternative_Method_Number_Of_Averages; 
    

  1. 它的身體alternative_method_number_of_averages.adb

    package body Alternative_Method_Number_Of_Averages is 
    
    --override this function 
    procedure Count_Averages (Any_Method : in out Second_Method; Sampling_Frequency, FFT_Size, Time_Recorded, Overlap_Fraction: in Float) is 
    begin 
        Any_Method.Number_Of_Averages := ((Sampling_Frequency * Time_Recorded) - FFT_Size)/(FFT_Size - Overlap_Fraction * FFT_Size) + 1.0; 
    end Count_Averages; 
    
    
    end Alternative_Method_Number_Of_Averages; 
    

然後在編制規範文件,我得到錯誤信息:

alternative_method_number_of_averages.ads:沒有選擇 「number_of_averages」 類型 「Second_Method」在alternative_method_of_averages.ads中定義。罪魁禍首是:

 Any_Method.Number_Of_Averages := ((Sampling_Frequency * Time_Recorded) - FFT_Size)/(FFT_Size - Overlap_Fraction * FFT_Size) + 1.0; 

那麼如何解決這個問題呢?

在我想年底前能有這樣的:在測試文件test_number_of_averages

 Number_Of_Averages.Count_Averages(Alternative_Method, Fs, NFFT, Time_Duration, Overlap_fraction); 

。亞行,類似於工作代碼

 Number_Of_Averages.Count_Averages(Good_Method, Fs, NFFT, Time_Duration); 

非常感謝......

UPDATE

所以,現在的替代方法的實現,我也有,改名爲Alternative_Method_Number_Of_Averages.ads/adbConventional_Method_Number_Of_Averages-Alternative_Method_Number_Of_Averages.ads/adb。測試文件是:

with Ada.Float_Text_IO; 
    with Ada.Text_IO; use Ada.Text_IO; 

    with Number_Of_Averages; 
    with Conventional_Method_Number_Of_Averages; 
    use type Number_Of_Averages.First_Method; 

    with Conventional_Method_Number_Of_Averages.Alternative_Method_Number_Of_Averages; 

    procedure Test_Number_Of_Averages is 

    Fs, Time_Duration, NFFT : Float := 0.0; 
    Averages1     : Float := 0.0; 
    Averages2     : Float := 0.0; 

    Good_Method     : Conventional_Method_Number_Of_Averages.First_Method; 
    Alternative_Method   : Conventional_Method_Number_Of_Averages.Alternative_Method_Number_Of_Averages.Second_Method; 

    begin 
    Ada.Text_IO.Put("Enter the sampling frequency "); 
    Ada.Float_Text_IO.Get (Item => Fs); 
    Ada.Text_IO.New_Line (1); 
    Ada.Text_IO.Put("Enter the time recorded "); 
    Ada.Float_Text_IO.Get (Item => Time_Duration); 
    Ada.Text_IO.New_Line (1); 
    Ada.Text_IO.Put("Enter the FFT size "); 
    Ada.Float_Text_IO.Get (Item => NFFT); 
    Ada.Text_IO.Put_Line (Ada.Text_IO.Get_Line); 

    Ada.Text_IO.New_Line(1); 
    Ada.Text_IO.Put("Number of averages = "); 
    Number_Of_Averages.Count_Averages(Good_Method, Fs, NFFT, Time_Duration); 

    Averages1 := Conventional_Method_Number_Of_Averages.Average_Is(Good_Method); 
    Ada.Float_Text_IO.Put (Item => Averages1, Fore => 3, Aft => 5, Exp => 0); 

    Ada.Text_IO.New_Line(1); 
    Ada.Text_IO.Put("Number of averages = "); 

    Number_Of_Averages.Alternative_Method_Number_Of_Averages.Count_Averages(Alternative_Method, Fs, NFFT, Time_Duration); 
    Averages2 := Conventional_Method_Number_Of_Averages.Alternative_Method_Number_Of_Averages.Average_Is(Alternative_Method); 
    Ada.Float_Text_IO.Put (Item => Averages2, Fore => 3, Aft => 5, Exp => 0); 

    end Test_Number_Of_Averages; 

隨着FS = 48000,TIME_DURATION = 60,NFFT = 8192,這兩種方法正在返回702.125。不管Overlap_Fraction參數如何,第二種方法總是返回702.125。如何在調用函數中指定Overlap_Fraction,同時仍然保持專用,即通過讓函數使用存儲在記錄中的Overlap_Fraction的值。

回答

3

Alternative_Method_Number_Of_Averages正文中,您嘗試使用Number_Of_Averages,它是父類型的私有成員。而且由於它是私人的,所以你不具有可視性。

當您使用軟件包時,您只能看到該規範的公開部分。

子包可以在其自己的公開部分中看到父公共部分的可見性,並且父包的私有部分在其私有部分中的可見性。

還有私人的孩子的,它有自己的規範整個母公司的知名度

要得到Number_Of_Averages知名度,你可以移動的全部類型聲明的公共部分,或使Alternative_Method_Number_Of_Averages的子包Conventional_Method_Number_Of_Average s。

有關詳細信息,看一看: http://en.wikibooks.org/wiki/Ada_Programming/Packages

在另一方面,壓倒一切的,只有當一種類型的擴展名正在實施完全相同的參數模板子程序在父發生。在你的例子中,Second_Method超載Count_Averages,即,添加一個新的子程序具有相同的名稱,但不同的配置文件。 Count_Averages仍然從具有較短參數配置文件的父級繼承。

+0

@ egilhh。謝謝。如何使Alternative_Method_Number_Of_Averages包含Conventional_Method_Number_Of_Averages的子包?我寧願將Number_Of_Averages保持爲私人。 1投票。 – yCalleecharan

+0

將程序包名稱更改爲:「程序包Conventional_Method_Number_Of_Averages.Alternative_Method_Number_Of_Averages爲」。您可能還必須更改文件名稱。 – egilhh

+0

@ egilhh謝謝。我做了必要的修改,但替代方法的結果給出了一個零,這是不正確的(雖然公式是好的)。我已更新該帖子。 – yCalleecharan