前回までは、 Pythonのデコレータについて、説明させていただきました。
公式や他サイト様の劣化焼き直しになっているようで、申し訳なく思います。
今回は、「C++ でデコレータをやってみた」というネタです。 前回までの投稿は、この説明のためでもありました。
元々、デコレータはデザインパターンなので、クラス階層で実装することができます。 しかし、ここではPython風に関数を基本に実装します。
C++11は使わず、C++03の制限内でやります。
関数ポインタ
デコレータは"関数を受けとり、関数を返す"関数を作れば OK です。 しかし、C++の関数は第一級ではないので、関数を受けとることも関数を返すことも一手間必要になります。 関数ポインタや関数オブジェクトという奴です。 まずは関数オブジェクトは後回しに、関数ポインタだけでいきます。
とりあえず、関数を受けとり、そのまま実行する方法を示します。
// main.cc
#include <stdio.h>
// /////////////////////////////////////////////////////////
// ==================================================
typedef int (*decorated_func_t)(int);
// ==================================================
int decorator(decorated_func_t a_Func, int a_Int) {
printf("KOOL!!! ");
return a_Func(a_Int) * 2;
}
// ==================================================
int hoge(int a_Int) {
return a_Int * 2;
}
// ==================================================
int main(int argc, const char* argv[]) {
printf("%d\n", decorator(&hoge, 10));
return 0;
}
先ず、typedef int (*decorated_func_t)(int);
で、関数ポインタの型を宣言します。
これで、decorated_func_tが関数ポインタを受け取れる型になります。
ただし、『戻り値がintで引数がint1つの関数』のみです。
main関数内の&hoge
が、関数のポインタを取得している部分です。
decoratatの第一引数がdecorated_func_t
なので、これを受け取ることができます。
関数ポインタはCでも使えるので、上記コードはC言語のみで記述しているのと同じです。
gcc --ansi main.cc -o main
./main
KOOL!!! 40
実行すると、decoratorから渡した10がhogeで2倍、decoratorで2倍と増えて、最終的に40が出力されています。
decorator(&hoge, 10)
が返すのは関数ではなく、実行した値であることに注意が必要です。
──続きます。
0 件のコメント:
コメントを投稿