第十四回-03 Studentクラスの配列とコレクション

Student クラスのインスタンスをたくさん用意すれば、学生のリストができあがる。 その方法をいくつか紹介する。

Student クラスの配列 (1)

まずは配列から。これは通常の変数の配列と変わらない。

(main 関数内)
	Student ss[3];  // 3つのオブジェクトに引数なしコンストラクタが呼ばれる

	ss[0].setStudent(101,"明智光秀");
	ss[1].setStudent(102,"豊臣秀吉");
	ss[2].setStudent(103,"徳川家康");

	for(int i=0 ; i<3 ; i++){
		ss[i].printInfo();
	}


Student クラスの配列 (2)

次に、ポインタを宣言して、オブジェクトの配列を new 演算子で動的に確保する場合。
これは第十一回-02の内容に類似している。

この方法は、コンパイル後に配列のサイズを決定できるというメリットがあるのだった。

(main 関数内)
	Student *ssp; // まずポインタを宣言

	ssp = new Student[3]; // 3つのオブジェクトに引数なしコンストラクタが呼ばれる

	ssp[0].setStudent(104,"毛利元就");
	ssp[1].setStudent(105,"武田信玄");
	ssp[2].setStudent(106,"上杉謙信");

	for(int i=0 ; i<3 ; i++){
		ssp[i].printInfo();
	}

	delete[] ssp;   // new で確保したメモリは自分で削除

通常の配列と、new で確保した配列とのメモリ上のイメージ図は以下の通り。



ところで、「ssp の指す先へのアクセスにはアロー演算子を用いるのではないか?」という疑問を持つ方がいるかもしれない。
実は、ポインタの指す先を配列として用いる場合はドット演算子になるのである。
ちなみに、「ssp->printInfo();」と記述すると「ssp[0].printInfo();」と同じ効果になる。

このあたりのややこしさは C++ 特有のもので、慣れと経験が必要なところ。


コレクション

最後に、配列とは異なるデータ構造としてリストと呼ばれるものを紹介する。 なお、リストとはコレクションと呼ばれるものの一つである。
C++ におけるコレクションは STL (Standard Template Library) の中で定義されており、 など、様々なものがある。

さて、配列は、データの個数によって決まる枠をあらかじめ決めておき、その中に何を格納する、というものであった。
そのため、配列は「データを次々と追加する」とか「一度登録したデータを削除する」という処理には向いていない
なぜなら、配列が格納できるデータの個数には制限があるし、またデータを削除したいと思っても、その配列の枠自体は消せないからである。

そのようなことが簡単にできるのがここで紹介するリストである。
リストの考え方自体は単純であり、下図のように、データを数珠つなぎにして保持するというものである。

データの追加は数珠つなぎのどこかにデータを挿入することで実現されるし、
データの削除はデータを取り去ってから数珠つなぎをつなぎ直すことで実現される



実際にリストを実装する際は上図の矢印をポインタで実現するのであるが、
ここではそこまで立ち入らず、STL にある list クラスを Student クラスに対して適用することを学ぼう。

まずは、main 関数外部に以下の include 文が必要である。

(main 関数外の先頭)
#include <list>

次に、main 関数内でリストを定義し、push_back 命令によりデータを次々と追加して行けば良い。
リスト内のデータをすべて表示するためにイテレータと for 文を組み合わせているのだが、
ここはやや難しいので、こうすれば全てデータを取り出せる、と思っておけば良い。

(main 関数内)
	std::list<Student> sl;  // リスト構造

	sl.push_back(Student(100,"織田信長"));
	sl.push_back(Student(101,"明智光秀"));
	sl.push_back(Student(102,"豊臣秀吉"));

	std::list<Student>::iterator itr; // イテレータ。リストの内部を辿る働きをする
	for (itr = sl.begin(); itr != sl.end(); ++itr)
	{
		itr->printInfo();
	}

また、リストからあるデータを削除するには以下のようにする。

(main 関数内)
	sl.remove(Student(100,"織田信長"));  // 登録した人を削除





←第十四回-02 Studentクラスの様々な呼び出し方第十四回課題→

非情報系学生のための C/C++ 入門に戻る