我正在尝试了解标记类型和代码扩展以及重用。我首先创建了一个程序conventional_method_number_of_averages
,它实现了一种计算方法。然后我使用标记类型的扩展并创建第二个程序alternative_method_number_of_averages
,它实现了解决相同问题的不同方法。不同的是,现在我多了一个parameter
叫overlap_fraction
. 这是一个简单的程序,第一种方法conventional_method_number_of_averages
可以正常工作:
number_of_averages.ads
with Conventional_Method_Number_Of_Averages; package Number_Of_Averages renames 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;
常规方法数平均数.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;
和测试文件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;
以上工作正常。
现在,如果我为相同的计算创建另一种方法,我有:
它的规范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;
和
它的主体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
存储在记录中的值。