タグ付けされた型とコード拡張を理解し、再利用しようとしています。conventional_method_number_of_averages
最初に、何らかの計算を行うための 1 つのメソッドを実装するプログラムを作成します。次に、タグ付きタイプの拡張を使用してalternative_method_number_of_averages
、同じ問題を解決する別の方法を実装する 2 つ目のプログラムを作成します。違いは、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;
従来の方法の数_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/adsの名前をConvention_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 を返します。ただし、2 番目の方法は、パラメーターに関係なく、常に 702.125 を返しOverlap_Fraction
ます。呼び出し元の関数で指定する方法Overlap_Fraction
で、それを非公開のまま使用する方法。つまり、関数Overlap_Fraction
にレコードに格納されている値を使用させる方法。