甲府方重信Blog

...Shigenobu Koufugatas Blog

  • Increase font size
  • Default font size
  • Decrease font size
Error
  • Unable to load Cache Storage: database
  • Unable to load Cache Storage: database
  • Unable to load Cache Storage: database
  • Unable to load Cache Storage: database
  • Unable to load Cache Storage: database
  • Unable to load Cache Storage: database
  • Unable to load Cache Storage: database
  • Unable to load Cache Storage: database
Home 業務日誌 Adaプログラミング Adaチュートリアル セクション11.1 ジェネリックスの定義

Adaチュートリアル セクション11.1 ジェネリックスの定義

E-mail Print PDF

セクション 11.1 - ジェネリックスの定義

サブプログラムやパッケージのより一般化したバージョンを最初に作成するのは、しばしば有効です。そして、その一般化されたバージョンをもっと特定のサブプログラムやパッケージを作成するのに用いるのです。このようなためにAdaには、ジェネリックと呼ばれている機能があります。これは、C++のテンプレートと同じ機能です。ジェネリックスは、C言語の#defineプリプロセッサー命令にどこか似たところがあります。しかし、Adaのジェネリックスは型チェックによって、より安全になっています。

 

 

サンプルコードを見ながら、ジェネリックスを理解するのがおそらくやさしいと思われます。最初に、二つの整数を入れ替えるプロシージャーを書きましょう。

  -- Here's the declaration (specification):
  procedure Swap(Left, Right : in out Integer);

  -- .. and here's the body:
  procedure Swap(Left, Right : in out Integer) is
    Temporary : Integer;
  begin
    Temporary := Left;
    Left := Right;
    Right := Temporary;
  end Swap;

Swapは、完全にすばらしいプロシージャーではありますが、少し特殊化されているきらいがあります。私たちは、Swapプロシージャーを浮動小数点数や、Unbounded文字列の入れ替えなどのためには使うことができないのです。私たちが求めているのは、Swapプロシージャーのより一般化されたバージョンなので、そこでは、整数型をより一般化した型で置き換える必要があるのです。Swapのジェネリック版は、次のようになります。

  -- Here's the declaration (specification):
  generic
    type Element_Type is private;
  procedure Generic_Swap(Left, Right : in out Element_Type);

  -- .. and here's the body:
  procedure Generic_Swap(Left, Right : in out Element_Type) is
    Temporary : Element_Type;
  begin
    Temporary := Left;
    Left := Right;
    Right := Temporary;
  end Generic_Swap;

一般的に言って、サブプログラム(もしくはパッケージ)のジェネリック版を作成するためには、いくつかの一般的な名前の型を使用してサブプログラムを書くことになります。次に、サブプログラムあるいはパッケージの前に、キーワード「generic」を宣言し、プログラマーがジェネリックにしたい情報のリスト置くのです。このリストは、ジェネリック・フォーマル・パラメーターと呼ばれ、プロシージャー宣言の引数リストのようになります。私たちは、この句「is private」が意味するところについては、後のセクションで説明します。

ジェネリックなサブプログラム(もしくはパッケージ)を使用するには、私たちは実際のサブプログラム(もしくはパッケージ)をジェネリックな版から生成しなくてはなりません。このプロセスは、インスタンシエイティングと呼ばれ、その結果はインスタンシエイション、もしくはインスタンスと呼ばれます。これらはシンプルな概念ながら重要な意味を持ちます。たとえば、ひとつのジェネリックから三種類Swapプロシージャーをどのように作るかお見せしましょう。

  procedure Swap is new Generic_Swap(Integer);
  procedure Swap is new Generic_Swap(Float);
  procedure Swap is new Generic_Swap(Unbounded_String);

プログラマーがジェネリックをインスタンシエイトするときに注意しなければならないのは、プログラマーが通常のプロシージャー呼び出しに引数を渡すのと同じような方法で、型を渡さなければならないことです。

ここからは、プログラマーは整数をとるSwapプロシージャーを呼び出すことができます。同じように、浮動小数点数、Unbounded文字列をとるプロシージャーといった形です。このように、もしAとBが整数型ならば、Swap(A,B)はそれらの値を入れ替えることが出来ます。そのほかにもあらゆるAdaのサブプログラムに対して、異なったサブプログラムが同じ名前を共有していれば、Adaはコンパイル時に引数の型を元に、特定のサブプログラムを決定することになります。

簡単なGeneric_Swapのテストプログラムを掲載します。

with Generic_Swap;

procedure Tswap is
 procedure Swap is new Generic_Swap(Integer);
 A, B : Integer;
begin
 A := 5;
 B := 7;
 Swap(A, B);
 -- Now A=7 and B=5.
end Tswap;

簡単にするために、私はプロシージャーSwapをプロシージャーTswapにインスタンシエイテッドしたところをお見せしました。しかし、多くの実際のプログラムは、ほとんどすべてのものものがパッケージの中に内包され、インスタンシエーションはパッケージ本体の内部で行なわれます。

出典: http://www.adahome.com/Tutorials/Lovelace/s11s1.htm

Last Updated on Tuesday, 13 March 2012 13:25  

ニュース速報

http://d.hatena.ne.jp/sesejun/20100902/p1

http://downloads.whamcloud.com/public/lustre/lustre-1.8.6-wc1/el5/server/i686/