我正在尝试理解标记类型和代码扩展以及重用。我首先创建一个程序conventional_method_number_of_averages
,它实现了一种计算方法。然后我使用标记类型的扩展并创建第二个程序alternative_method_number_of_averages
,它实现了解决相同问题的不同方法。不同的是,现在我有一个名为parameter
的{{1}}。这是一个简单的程序,第一个方法overlap_fraction
可以正常工作:
number_of_averages.ads
conventional_method_number_of_averages
conventional_method_number_of_averages.ads
with Conventional_Method_Number_Of_Averages;
package Number_Of_Averages renames Conventional_Method_Number_Of_Averages;
conventional_method_number_of_averages.adb
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;
和测试文件 test_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;
以上工作正常。
现在,如果我为同一计算创建一个替代方法,我有:
其规格 alternative_method_number_of_averages.ads
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.adb
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.ads:在alternative_method_of_averages.ads中定义的类型“Second_Method”没有选择器“number_of_averages”。罪魁祸首是:
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;
那么如何解决这个问题?
最后,我希望能够有类似的东西:
Any_Method.Number_Of_Averages := ((Sampling_Frequency * Time_Recorded) - FFT_Size) / (FFT_Size - Overlap_Fraction * FFT_Size) + 1.0;
在测试文件 test_number_of_averages.adb 中,与工作代码类似
Number_Of_Averages.Count_Averages(Alternative_Method, Fs, NFFT, Time_Duration, Overlap_fraction);
非常感谢...
更新
现在,对于替代方法实现,我已将 Alternative_Method_Number_Of_Averages.ads/adb 重命名为 Conventional_Method_Number_Of_Averages-Alternative_Method_Number_Of_Averages.ads/adb 。测试文件是:
Number_Of_Averages.Count_Averages(Good_Method, Fs, NFFT, Time_Duration);
当Fs = 48000,Time_Duration = 60,NFFT = 8192时,两种方法都返回702.125。但是第二种方法总是返回702.125而不管 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;
参数。如何在调用函数中指定Overlap_Fraction
,同时仍保持私有使用,即让函数使用存储在记录中的Overlap_Fraction
值。
答案 0 :(得分:3)
在Alternative_Method_Number_Of_Averages
的正文中,您尝试使用Number_Of_Averages
,它是父类型的私有成员。因为它是私人的,
你没有它的可见性。
当您使用包时,您只能看到规范的公共部分。
子包将在其公共部分中显示父项的公共部分,并且可以在其私有部分中查看父项的私有部分。
还有私人孩子,它们在自己的规范中可以看到整个父母
要获得Number_Of_Averages
的可见性,您可以将完整类型声明移至公共部分,也可以使Alternative_Method_Number_Of_Averages
成为Conventional_Method_Number_Of_Average
的子包。
有关详细信息,请查看: http://en.wikibooks.org/wiki/Ada_Programming/Packages
另一方面,仅当类型扩展实现具有与父级中相同的精确参数配置文件的子程序时才会发生覆盖。在您的示例中,Second_Method
正在重载Count_Averages
,即添加具有相同名称但不同配置文件的新子程序。 Count_Averages
仍然使用较短的参数配置文件从父级继承。