前担任学生さんより…
前回担任したクラスの女子学生さん(今はバリバリ仕事?)から、 結婚&出産&産休中の連絡をもらう。 うちの奥さんは産休も短かったけど、彼女はうまく育休もとれてるみたい。
産後1月ほどみたいだけど、自分の時の記憶じゃ、かわいいんだけど、 夜中にオムツ交換で、奥さんと「次はお前…」シグナルを『足』で送りあっていたころだな…
泡は出ないのかょ…
職場の売店の新商品のお茶。 ラベルを見ると泡を期待してしまう…
純粋仮想クラス
先週の仮想関数のより実践的な使い方として、 純粋仮想クラスの使い方を紹介する。
この方法を使えば、新しいデータ構造が必要となっても、 基底クラスから派生させたデータ構造と、 必要最小限の仮想関数の定義だけで、プログラムが書けることを強調する。
C言語を習っただけの学生対象の授業であるため、"using namespace std;" といった文法は一切使わない。
#include <stdio.h> #include <string.h> // 純粋仮想基底クラス // 処理を呼び出すためだけの目的の入れ物クラス class Object { public: // データを比較するための仮想関数。 // 単なる入れ物なので、比較する処理を書けない virtual int cmp( Object* ) = 0 ; // データを表示するための仮想関数 virtual void print() = 0 ; } ; // データの並べ替えをする関数 void sort( Object* array[] , int size ) { // 最大選択法 for( int i = 0 ; i < size - 1 ; i++ ) { int m = i ; for( int j = i + 1 ; j < size ; j++ ) { // array[i]とarray[j]を比較。 // array[i]>array[j] なら正の値 // = なら0 , < なら負の値 int ans = array[m]->cmp( array[j] ) ; // より大きい値を見つけたらmに場所を保存 if ( ans < 0 ) m = j ; } // i+1〜最後の範囲の最大(m番目)と先頭を入替え Object* tmp = array[ i ] ; array[ i ] = array[ m ] ; array[ m ] = tmp ; } } // Objectに整数を追加したデータ class Integer : public Object { private: int data ; public: // 整数データのコンストラクタ Integer( int x ) : data( x ) {} // 整数の比較を行う仮想関数を具体的に定義 virtual int cmp( Object* p ) { return data - ((Integer*)p)->data ; } // データを表示する仮想関数を具体的に定義 virtual void print() { printf( "%d\n" , data ) ; } } ; // Objectに文字列を追加したデータ class Cstring : public Object { private: char const*const data ; public: Cstring( char const*const s ) : data( s ) {} // 整数の比較を行う仮想関数を具体的に定義 virtual int cmp( Object* p ) { return strcmp( ((Cstring*)p)->data , data ) ; } // データを表示する仮想関数を具体的に定義 virtual void print() { printf( "%s\n" , data ) ; } } ; int main() { // 配列aに72,12,25,6を保存 Object* a[] = { new Integer( 72 ) , new Integer( 12 ) , new Integer( 25 ) , new Integer( 6 ) } ; // データを並び替える sort( a , 4 ) ; // 並び替えた結果の表示 for( int i = 0 ; i < 4 ; i++ ) a[ i ]->print() ; // Cstringでも使えることを実験 Object* b[] = { new Cstring( "orange" ) , new Cstring( "grape" ) , new Cstring( "apple" ) , new Cstring( "pine apple" ) , new Cstring( "peach" ) , } ; sort( b , 5 ) ; for( int i = 0 ; i < 5 ; i++ ) b[ i ]->print() ; return 0 ; }
C++の文法をちゃんと使おう
比較関数int cmp( Object* ) における、型キャストが説明不足なので、 C言語の基礎知識としてのキャスト演算子の説明(実数整数変換を例とした)を行う。
ただし、C言語の型キャストでの方式は、時代に乗り遅れているので、 このページ上は最近のキャストの使い方を記載しておこう。
最近のC++であれば、以下のような書き方をすべき。
virtual int cmp( Object* p ) { Integer* ip = dynamic_cast<Integer*>(p) ; if ( ip != NULL ) return data - p->data ; } else { return 0 ; // 比較に失敗 } }