1

我正在尝试了解标记类型和代码扩展以及重用。我首先创建了一个程序conventional_method_number_of_averages,它实现了一种计算方法。然后我使用标记类型的扩展并创建第二个程序alternative_method_number_of_averages,它实现了解决相同问题的不同方法。不同的是,现在我多了一个parameteroverlap_fraction. 这是一个简单的程序,第一种方法conventional_method_number_of_averages可以正常工作:

  1. number_of_averages.ads

    with Conventional_Method_Number_Of_Averages;
    package Number_Of_Averages renames Conventional_Method_Number_Of_Averages;
    
  2. 常规方法数平均数.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. 常规方法数平均数.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:在alternative_method_of_averages.ads 中定义的类型“Second_Method”没有选择器“number_of_averages”。罪魁祸首是:

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

那么如何解决这个问题呢?

最后,我希望能够拥有类似的东西:

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

在测试文件test_number_of_averages.adb中,与工作代码类似

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

非常感谢...

更新

所以现在对于替代方法的实现,我将Alternative_Method_Number_Of_Averages.ads/adb重命名为Conventional_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。第二种方法总是返回 702.125 而与Overlap_Fraction参数无关。如何Overlap_Fraction在调用函数中指定,同时仍然保持私有,即让函数使用Overlap_Fraction存储在记录中的值。

4

1 回答 1

3

Alternative_Method_Number_Of_Averages您尝试使用的正文中Number_Of_Averages,它是父类型的私有成员。而且由于它是私有的,因此您无法看到它。

当您使用软件包时,您只能看到规范的公共部分。

子包将在其自己的公共部分中看到父包的公共部分,并在其自己的私有部分中看到父包的私有部分。

还有私人孩子,在自己的规范中可以看到整个父母

要获得 s 的可见性Number_Of_Averages,您可以将完整的类型声明移至公共部分,或制作sAlternative_Method_Number_Of_Averages的子包Conventional_Method_Number_Of_Average

有关更多详细信息,请查看: http ://en.wikibooks.org/wiki/Ada_Programming/Packages

另一方面,仅当类型扩展正在实现具有与父级完全相同的参数配置文件的子程序时,才会发生覆盖。在您的示例中,Second_Method是重载Count_Averages,即添加一个名称相同但配置文件不同的新子程序。Count_Averages仍然从具有较短参数配置文件的父代继承。

于 2012-08-27T07:49:12.833 回答