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