ホーム » スタッフ » 斉藤徹 » GrWinを用いた仮想関数演習の考え方

2009年6月
« 5月   7月 »
 123456
78910111213
14151617181920
21222324252627
282930  

最近の投稿(電子情報)

アーカイブ

カテゴリー

GrWinを用いた仮想関数演習の考え方

仮想関数と派生を理解した後の、グラフィックスの演習で、 図形クラスより、より具体的な四角クラス・丸クラスを作り、 この処理に色を使うクラスを追加するのが演習の目標。 これにより、色の取り扱いを、様々なクラス階層で作れることを考えてもらいたい。

しかし、C++初体験組が多いし、上位クラスのメソッドを呼び出すために、 クラス指定子「クラス::メソッド()」なんかの説明も足りないので、 ヒントをWebに掲載する。

単純に基底クラスが色を持つ

色を追加する際に、サンプルで示した処理の中に色を埋め込ませる事例。 色の取り扱いのために追加した部分が、元プログラムの中に色々と組み込まれる。

// 基底クラスが色の情報を持つ
//      Figure(color)
//        ↓派生
//      FigureBox(width,height)
class Figure {
private:
int color ;  // 色を追加(元サンプルでは、何も無かったけど)
public:
Figure( int col )  // 色付き基底クラスのコンストラクタ
: color( col ) {}
virtual void draw( int , int ) {
// 描画の前に色を設定
GWsetpen( color , 1 , 1 , -1 ) ; // 色以外は基本設定
}
} ;
class FigureBox : public Figure { // 派生クラスで色の処理を追加
private:
int width , height ;
public:
FigureBox( int col , int w , int h )
: Figure( col ) ,  // 色付き基底クラスを初期化
width( w ) ,
height( h ) {}
virtual void draw( int x , int y ) {
Figure::draw( x , y ) ; // 基底クラスで色を設定
// ここに四角を描く処理
}
} ;
int main() {
FigureBox cbox( 13 , 100 , 100 ) ; // 赤い100x100のBox
cbox.draw( 10 , 10 ) ; // (10,10)にBoxを描く
:
}

既存クラスを流用し色の扱いを追加

元のプログラムを触らず、追加した色のクラスをさらに派生させる考え方。

// 色を持った派生クラスを作る
//      Figure(無し) 純粋基底クラス
//        ↓派生
//      FigureBox(width,height)
//        ↓派生
//      FigureBoxColor(color)
class FigureBoxColor : public FigureBox { // FigureBoxに色を追加
private:
int color ;
public:
FigureBoxColor( int x , int y , int col )
: FigureBox( x , y ) , // 基本となるクラスを初期化
color( col ) {}  // 追加された色を初期化
virtual void draw( int x , int y ) {
GWsetpen( color , 1 , 1 , -1 ) ;  // 描画の前に色を設定
FigureBox::draw( x , y ) ;
}
} ;
int main() {
FigureBoxColor cbox( 100 , 100 , 13 ) ;
cbox.draw( 10 , 10 ) ;
:
}

既存クラスを流用し多重継承を使ってみる

元のプログラムを触らず、追加した色のクラスも多重継承を用いる考え方。 Javaならば、インタフェース機能などを使わないとダメなケース。

ただし、FigureBoxColorと、FigureBoxCircleを派生させたあとで、 「指定した色で四角の中に丸が描かれるような1図形」などといった 要求がでてきたら、ダイヤモンド型の派生となる。 こういう場合がどういったデータ構造になるのかが、注目すべき事例。

// 多重継承で動かしてみる
//      Figure(無し)
//       派生↓
//      FigureBox   Color(color)
//          派生\  /派生
//         FigureBoxColor
class Color {
private:
int color ;
public:
Color( int col )  // 色を初期化
: color( col ) {}
void setcolor() { // 描画前に色を設定するメソッド
GWsetpen( color , 1 , 1 , -1 ) ;
}
} ;
class FigureBoxColor : public FigureBox , public Color {
public:
FigureBoxColor( int w , int h , int col )
: FigureBox( w , h ) , // 基底クラスの初期化
Color( col ) {}  // 色クラスを初期化
virtual void draw( int x , int y ) {
色を設定する処理を呼び出す。
FigureBoxのdrawを呼び出す。
}
} ;