2012-08-27 86 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