データ構造とイメージ図
昨年度のテスト問題で、構造体の配列の作り方とそのイメージ図についての 問題で質問が多かったので、解説を行った。
//2件のComplex型を配列に入れる。 struct Complex { double re , im ; } ; // (A) 単純な配列 struct Complex table[ 2 ] ; // (B) 配列サイズを可変にする場合 struct Complex* table ; table = (struct Complex*)malloc( sizeof( struct Complex ) * 2 ) ; if ( table != NULL ) { table[0].re = 1 ; table[0].im = 2 ; table[1].re = 3 ; table[1].im = 4 ; } // (C)実体参照をポインタにする場合 struct Complex* table[ 2 ] ; table[0] = (struct Complex*)malloc( sizeof( struct Complex ) ) ; if ( table[0] != NULL ) { table[0]-> = 1 ; table[0]-> = 2 ; } table[1] = (struct Complex*)malloc( sizeof( struct Complex ) ) ; if ( table[1] != NULL ) { table[1]-> = 3 ; table[1]-> = 4 ; } // (D)可変配列サイズでポインタ参照 struct Complex** table ; table = (struct Complex**)malloc( sizeof( struct Complex* ) * 2 ) ; if ( table != NULL ) { table[0] = (struct Complex*)malloc( sizeof( struct Complex ) ) ; if ( table[0] != NULL ) { table[0]-> = 1 ; table[0]-> = 2 ; } table[1] = (struct Complex*)malloc( sizeof( struct Complex ) ) ; if ( table[1] != NULL ) { table[1]-> = 3 ; table[1]-> = 4 ; } }
(A)は、最も基本の配列。 (B)は、配列サイズが実行時に決められない時で、 可変配列サイズの場合にとる方法。 (C)は、構造体のComplex型で、もし巨大なメモリを消費する場合、 例えば配列のソートでデータ入れ替えがある場合、 巨大構造体であれば、巨大なメモリをコピーするのは時間がかかる。 (C)の例の様にポインタで実体を参照する方法であれば、 データ入れ替えもポインタの入れ替えだけで可能となる。 (D)は、(B)と(C)のテクニックのあわせ技。 この様に、配列サイズが可変なのか、実体入れ替えが容易なのか… という状況に応じて、これらのデータ構造の実装方法を選べることが重要。
純粋仮想基底クラスと課題、多重継承
先週、仮想関数の話をしたので、実際の仮想関数の応用をネタに説明を行う。
コンテナクラスライブラリへの応用
まず、コンテナクラスの説明として、配列のソートを仮想関数を用いたら、 どうやって書けるかを資料を見せながら説明する。 純粋基底クラスObjectを定義し、比較の仮想関数を定義し、 class Integer : Object {…} , class Cstring : Object {…} といった派生クラスと、 比較関数を定義すれば、どんなデータ構造のソートも簡単に書けることを説明。
ただ、コンテナクラスは簡単なデータの場合では、実装効率が悪いため、 最近ではTemplate機能が多様されていることを紹介する。 特に、C++ではSTLなどのTemplateライブラリが発達している。
課題と多重継承問題
次に、課題として、GrWin を使ったグラフィックスで、図形クラスFigureを定義し、 その派生クラス class FigureBox : Figure {…} , class FigureCircle : Figure {…} を 生成して、四角や丸を描く処理が書けたり、
Object* array[] = { new FigureBox(...),new FigureCircle(...) } ;
といった異なる図形が混在したデータ構造でプログラムが書けるといった例を説明し、 レポートでは、他の図形を追加せよ…と課題の説明。
この課題のポイントは、色付き図形の扱い。 Figureに色を持たせる、 FigureBoxから色付きFigureBoxを派生させる、 Color基底クラスを作り色付きFigureBoxでは、Figure,Colorの多重継承… といった様々な方法があることを説明する。
んで、様々な考え方の中の多重継承の紹介を行う。 定番の、生物界のクラスで、カモノハシが鳥類と哺乳類の多重継承でプログラムを作ると、 その最上位基底クラス「生物」でを2重で持たないための煩雑さ、 鳥類と哺乳類で同名の別メソッドがあった場合の曖昧さの問題があることを紹介する。 このため、C++では多重継承機能が使えるが、 Javaでは多重継承を禁止し、Interface 機能を使うことを紹介する。