1

タグ付けされた型とコード拡張を理解し、再利用しようとしています。conventional_method_number_of_averages最初に、何らかの計算を行うための 1 つのメソッドを実装するプログラムを作成します。次に、タグ付きタイプの拡張を使用してalternative_method_number_of_averages、同じ問題を解決する別の方法を実装する 2 つ目のプログラムを作成します。違いは、parameterと呼ばれる追加があることoverlap_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. 従来の方法の数_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. 従来法平均数.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/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にレコードに格納されている値を使用させる方法。

4

1 に答える 1

3

の本体で、親型のプライベート メンバーであるAlternative_Method_Number_Of_Averagesを使用しようとしています。Number_Of_Averagesまた、プライベートであるため、表示することはできません。

パッケージを使用すると、仕様の公開部分のみが表示されます。

子パッケージは、それ自体のパブリック パーツで親のパブリック パーツの可視性を持ち、独自のプライベート パーツで親のプライベート パーツの可視性を持ちます。

独自の仕様で親全体を表示できるプライベートな子もあります

の可視性を得るにはNumber_Of_Averages、完全な型宣言を public 部分に移動するか、 s のAlternative_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 に答える