のんびりしているエンジニアの日記

ソフトウェアなどのエンジニア的な何かを書きます。

C++ 関数ポインタ(メンバ関数+関数)

Sponsored Links

皆さんこんにちは
お元気ですか?私は元気です。

さて、今日は関数ポインタについて

関数ポインタの利点

関数ポインタを使うと、テーブルとして関数を引けるので、処理が簡単になります。
例えば以下のようなコードが有ります。(add,mulは定義されているとします)

int algorithm = 1
if(algorithm == 0){
    add(2,3);
}else if(algorithm == 1){
    mul(3,4);
}

このコードは追加する時に分岐を増やすという面倒なことになります。いやはや面倒
これを関数ポインタを使って書くと、このようになります。

int (*func[])(int,int) = {add,mul};
cout << (*func[0])(10,20) << endl;

楽です。追加するときも一箇所だけでとても楽です。

実際の記載例

さて、プログラムですが、以下の例を作ってみました。

#include <iostream>

using namespace std;

int add(int a,int b){
	return a + b;
}

int mul(int a,int b){
	return a * b;
}

class Function{
public:
	int diff(int a,int b){
		return a - b;
	}

	int mul(int a,int b){
		return a * b;
	}

	int calc(int index){
		int (Function::*class_funcs[2])(int,int) = {&Function::diff,&Function::mul};
		return (this->*class_funcs[index])(300,30);
	}
};

int main(int argc, char const *argv[]){
	int (*func[])(int,int) = {add,mul};

	//関数ポインタ
	cout << (*func[0])(10,20) << endl;
	cout << (*func[1])(10,20) << endl;

	Function fc;
	//メンバ関数ポインタ
	int (Function::*class_func)(int,int) = &Function::diff;
	cout << (fc.*class_func)(10,20) << endl;

	//メンバ関数ポインタ配列
	int (Function::*class_funcs[2])(int,int) = {&Function::diff,&Function::mul};
	cout << (fc.*class_funcs[0])(10,20) << endl;
	cout << (fc.*class_funcs[1])(300,20) << endl;

	cout << fc.calc(0) << endl;
	cout << fc.calc(1) << endl;

	return 0;
}

結果

30
200
-10
-10
6000
270
9000

通常の関数のポインタ

int (*func[])(int,int) = {add,mul};

戻り値(ポインタ)(<引数>) = {<関数>}の形式で記載することができる。

メンバ関数のポインタ

メンバ関数のポインタはこんな感じ

int (Function::*class_funcs[2])(int,int) = {&Function::diff,&Function::mul};
cout << (fc.*class_funcs[0])(10,20) << endl;

戻り値(Class::pointer名)(<引数>) = {関数}
出力は
(インスタンス.*関数ポインタ)(<引数>)

まとめ

関数ポインタ関連の使い方は以下の通り
通常の関数ポインタ
戻り値(ポインタ)(<引数>) = {<関数>}

メンバ関数ポインタ
戻り値(Class::pointer名)(<引数>) = {関数}
(インスタンス.*関数ポインタ)(<引数>)