派生と継承の基本の説明をしてきたので、次に説明する予定の仮想関数の導入として、 実装のために使われている関数ポインタを紹介。
関数ポインタ
関数ポインタとは、関数へのポインタであり、ポインタを変更することで、 処理を切り替えるために使われる。 まずは、動作説明の簡単なプログラムを紹介。
int add( int x , int y ) { // 加算関数 return x + y ; } int mul( int x , int y ) { // 乗算関数 return x * y ; } void main() { int (*f)(int,int) ; // int×2引数、返り値intの関数へのポインタ f = add ; printf( "%d" , (*f)( 2 , 3 ) ) ; // 5を表示 f = mul ; printf( "%d" , (*f)( 2 , 3 ) ) ; // 6を表示 }
関数ポインタを利用すれば、異なるデータに対する処理を、 汎用性高く作ることも可能となる。 例えば以下の vmax() 関数は、自分で用意した大小を比較するだけの関数を渡し、 それ以外の最大値を求めるための処理を行う。 このため、他のデータの最大値を求めたい場合でも、最大値を求める処理を すべて記載するのではなく、対象データの比較関数だけを記述すれば良い。
int intcmp( int* x , int* y ) { // 整数比較関数 if ( *x > *y ) return 1 ; else if ( *x < *y ) return -1 ; else return 0 ; } int vmax( void* array , // 配列先頭アドレス int size , // 配列データ件数 int sizeofdata , // 1件あたりのbyte数 int(*f)( void*,void* ) ) { // 比較関数 int i , max = 0 ; for( i = 0 ; i < size ; i++ ) if ( (*f)( array + max * sizeofdata , array + i * sizeofdata ) ) max = i ; return max ; } int idata[ 4 ] = { 11 , 33 , 22 , 44 } ; char sdata[ 4 ][ 4 ] = { "ab" , "bc" , "aa" , "c" } ; void main() { int m ; // intcmp関数を使って、idata から最大値を探す m = vmax( idata , 4 , sizeof(int) , intcmp ) ; printf( "%d" , idata[ m ] ) ; // strcmp関数を使って、sdata から最大値を探す m = vmax( sdata , 4 , sizeof(sdata[0]) , strcmp ) ; printf( "%s" , sdata[ m ] ) ; }