C++言語解説:STL基礎(1)STL概要とコンテナ
2003-08-09

[概要] STLの概要として目的と構成を説明します。実際に少しだけSTLのコーディングを
    体験し、STLを利用したプログラミングの導入とします。

[構成]・学習の前に
     * 必要な予備知識について
   ・STLの概要
     * STLの目的
     * STLの構成要素
   ・STLプログラミングの具体例
     * vectorコンテナ概要
     * vectorコンテナの簡単な利用例


●学習の前に

 ◆必要な予備知識について
 
  ・本レポートではSTLの基本を数回に渡って紹介します。STLのアウトライン把握と、
   詳細学習への動機付けを目的としています。
  
  ・STLはC++のプログラミング効率向上を目指したものです。従ってC++自身について
   予備知識のあること
が、本レポートを読む上での前提となります。
  
  ・特にクラスとテンプレートの知識は欠かせません。ここに不安を感じるのであれば
   他のレポート(クラス/テンプレート)や参考書を一読して頂きたいと思います。



●STLの概要

 ◆STLの目的
 
  ・STLStandard Template Libraryの略です。従来のプログラミングで使用される
   ータ構造とアルゴリズムをC++で実装したクラス及び関数テンプレートの集合
です。
  
  ・そもそもプログラムの基本はデータ構造とアルゴリズムであり、これらは密接に絡
   み合っています。
  
  ・従来のCプログラミングでは、使用できるデータ型が限られていたため、それらを
   扱うアルゴリズムも定型的準備で済みました。その結果アルゴリズムとして何らか
   の形で準備されたライブラリを使用することは、比較的容易に可能でした。
  
  ・しかし、C++でオブジェクト指向プログラミングが導入され、プログラムの扱うデ
   ータ単位がオブジェクトになってから、従来の作り方では、他者の作成したライブ
   ラリを流用することが難しく
なってきました。
  
  ・そこでC++では汎用的なオブジェクトを扱うデータ型とアルゴリズムを扱うテンプ
   レートライブラリを標準として用意
しました。それがSTLです。
  
  ・つまり標準C++に準拠した環境であれば、STLを利用することができます。これには
   C++プログラミングの効率を大きく向上させる可能性があります。
  
  ・またSTLが持つプログラミングスタイル。これはオブジェクト指向プログラミング
   における良いサンプルの一つ
となっています。こういった幾つかの長所から、STL
   プログラミングを学ぶことは必須となりつつあります。


 ◆STLの構成要素
 
  ・STLは以下の要素で構成されます。(*1)
  
   * コンテナ
     + コンテナ(container)オブジェクトを格納し、メモリへの配置を定義するオ
      ブジェクト
です。例えばリストや連想配列が、コンテナに該当します。
     + コンテナには各要素を操作するためのメンバ関数が実装されています。
   
   * アルゴリズム
     + ソートやサーチ等のアルゴリズム(algorithm)はコンテナを扱います。アル
      ゴリズムはコンテナを通してユーザ定義のオブジェクトに作用します。
   
   * 反復子
     + 反復子(iterator)は要素の位置を示すオブジェクトです。
     + 先ほどコンテナにはメンバ関数が実装されていると書きましたが、ほとんど
      の場合は、この反復子と合わせて利用します。
   
   * アロケータ
     + 各コンテナはアロケータ(allocator)を持ちます。
     + アロケータはコンテナの割り当てメモリを管理しますが、ほとんどの場合デ
      フォルトで用意されるアロケータで十分です。
  
  ・大まかに言うと、自分の作成した複数のオブジェクトに一般的なアルゴリズムによ
   る処理を加えたい場合、従来であれば、専用の関数やクラスを作成する必要があり
   ました。
  
  ・しかしSTLを使えば、対象オブジェクトをコンテナが定義するメモリ配置にしてし
   まえば、あとはアルゴリズムが適用できてしまう
わけです。新規のクラスを生成す
   るたびに一般的な処理を行う関数/クラスを作成する手間が省け、プログラムのコ
   ーディング/デバッグ効率は大幅に向上すると考えられます。

  ┌────────────────────────────────────┐
       ■   ●    複数のオブジェクト
       │ ◆ │ ▲
   --------│--│--│--│-----------------------------------------
       ↓ ↓ ↓ ↓
      ┌─┬─┬─┬─┬─ 追加    コンテナに格納
    ┌→│■│◆│●│▲│◎ ←─ ◎  メモリ配置は線形/連想等
    │ └─┴─┼─┴─┴─      格納後もデータ操作
    │     ↑           メモリはアロケータ管理
    │  反復子で位置指定
    │
   --│-----------------------------------------------------------
    └─────┐
          │
     コンテナ要素を対象にアルゴリズムで処理
     ソート、サーチ等々....
  └────────────────────────────────────┘
   Fig.1 STL構成要素の利用


●STLプログラミングの具体例

 ◆vectorコンテナ概要
 
  ・STLプログラミングを体験するためにvectorコンテナを使用します。プログラミン
   グ例を理解するために最低限必要な内容だけ説明します。
  
  ・vectorは動的な配列を提供するコンテナです。以下のテンプレート仕様です。
    template <class T, class Allocator = allocator<T>> class vector
  
  ・今回の例では以下のコンストラクタとメンバ関数を使用します。

   * コンストラクタ
     + explicit vector(const Allocator& a = allocator);
       空のベクタを作成します
   
   * メンバ関数
     + void push_back(const T& val);
       valと同じ値の要素をベクタ末尾に追加します
     + int size() const;
       ベクタに格納されている要素数を返します
  
  ・vectorコンテナを利用するには <vector>ヘッダをincludeする必要があります。
 
 
 ◆vectorコンテナの簡単な利用例
 
  ・標準入力からデータを読み込み、合計/平均/標準偏差を算出するプログラムを
   vectorコンテナで作成してみます。
  
  [List1.vectorコンテナの使用例]
  ┌────────────────────────────────────┐
   // +----+
   // | 70 | データファイルを標準入力からプログラムへ
   // | 20 |  Sum : 440
   // | 40 |  Average : 55
   // | 30 |  Index : 8
   // | 60 |
   // | 90 |
   // | 80 |
   // | 50 |
   // +----+
   
   #include <iostream>
   #include <vector>

   using namespace std;

   int main() {
     int i_buf;
     vector<int> Vector; //空のvectorコンテナ定義
  
     while(!cin.eof()){
       cin >> i_buf;
       Vector.push_back(i_buf); //要素追加
       cout << "data=" << Vector[Vector.size()-1]; //要素表示
       cout << ", index " << Vector.size() << endl;
     }
  
     int sum = 0;
  
     for (int index=0; index < Vector.size(); index++) {
       sum += Vector[index];
     }
  
     cout << "sum = " << sum << endl;
     cout << "average = " << sum/Vector.size() << endl;
     cout << "index = " << Vector.size() << endl;
  
     return 0;
   }
  └────────────────────────────────────┘
  ┌────────────────────────────────────┐
   [出力結果]
   data=70, index 1
   data=20, index 2
   data=40, index 3
   data=30, index 4
   data=60, index 5
   data=90, index 6
   data=80, index 7
   data=50, index 8
   sum = 440
   average = 55
   index = 8
  └────────────────────────────────────┘
  
  ・このプログラムでは最初に空のvectorコンテナ「Vector」を用意し、標準入力cin
   から読んだデータを順次格納
しています。
  
  ・データ格納後、各要素の値を合計し、平均と要素数も表示しています。
  
  ・着目すべき点は、vectorはデータを読みながら動的にデータ要素を追加しているこ
   とです。vectorコンテナを使わずにこの動きを実現するにはnew演算子+構造体 or
   classを適用する必要があることは容易に想像できるでしょう。
  
  ・しかも、要素には添字[]指定でアクセス可能です。vectorコンテナクラスは[]の演
   算子を有しているから
です。ただし、STLの基本スタイルでは反復子を使用するので
   この例はある意味特別です。
  
  ・配列のサイズも動的に把握することができます。この程度のサンプルでも通常の配
   列に比べてメリットが多いことを実感できると思います。
  
  ・このサンプルでは見えない例として「境界検証機能」があります。通常の配列では
   非メモリ確保領域にアクセスしてもエラーになりません(落ちてしまう)が、vector
   コンテナを使用した場合、ランタイムエラーとして検出することが可能です。
  
  ・感覚的に少し馴染んだでしょうか? 次回は反復子を利用してSTLのプログラミング
   スタイルに少しずつ慣れていきたいと思います。


(*1)その他に関数オブジェクトやアダプタが要素として存在しますが、今回のレポートで
  は割愛します。STLの基礎編最後で関数オブジェクトを紹介する予定です。

[Revision Table]
 |Revision |Date    |Comments
 |----------|-----------|-----------------------------------------------------
 |1.00   |2003-08-09 |初版
 |1.01   |2003-08-10 |リンク追加、誤字修正
[end]
Copyright(C) 2003 Altmo