この記事には複数の問題があります。改善
やノートページでの議論にご協力ください。関数オブジェクト(かんすうオブジェクト、英: function object)は、プログラミング言語において、関数(サブルーチンまたはプロシージャ)を、オブジェクトとしたものである。@media screen{.mw-parser-output .fix-domain{border-bottom:dashed 1px}}手続きオブジェクトとも言う(プロシージャ=手続き)[要出典]。なお、ここでのオブジェクトの語は、いわゆるオブジェクト指向のそれに限らず、「第一級オブジェクト」という語におけるのと同じ、メモリ上に領域を確保されたもの、といった意味である。関数が第一級オブジェクトである場合は特に第一級関数と言う。
関数と変数の名前空間が共通である言語の場合[要追加記述]、構文の設計によっては、y = f(x) といったような、通常のサブルーチン呼び出しと全く同じ構文で、関数オブジェクトが保持しているサブルーチンを呼び出せる言語もある。一方、通常のサブルーチンのように呼び出すことはできず、applyやacceptやgetといった特別な名前のメソッドを経由して呼び出す必要のある言語もある。
また、変数束縛が閉じられた関数オブジェクトはクロージャである。C#などの.NET言語には関数オブジェクトのようなものとして、オブジェクトのインスタンスとその振る舞いであるメソッドとを結びつけて管理することのできる、デリゲートがある。無名関数も参照。 関数オブジェクトの典型的な用途は、より優れたコールバックを記述することである。C言語では、コールバックには関数へのポインタを使う他ないが、コールバックの内外で状態変数を共有できない。この制限のために、関数の動的な振る舞いやインターフェイス設計が制約されてしまう。以下に例を示す。/* ライブラリ側のコード */typedef void my_callback_func_t(void);typedef struct my_handler { my_callback_func_t* callback;} my_handler_t;void register_callback(my_handler_t* handler, my_callback_func_t* func) { handler->callback = func;}void invoke_callback(my_handler_t* handler) { if (handler->callback) { handler->callback(); }}void perform_process(my_handler_t* handler) { /* 前処理 */ /* ... */ /* コールバック関数の呼び出し */ invoke_callback(handler); /* 後処理 */ /* ... */}/* アプリケーション側のコード */void callback_func(void) { /* ... */ /* ここで後述の状態変数 state にアクセスしたくても、不可能 */}int main(void) { /* 状態変数 */ static int state = 0; my_handler_t handler = { NULL }; /* コールバックとして callback_func という関数へのポインタを登録 */ register_callback(&handler, &callback_func); perform_process(&handler);} コールバック関数内で外部の状態変数を参照するためには、グローバル変数を利用したり、構造体メンバーに状態変数へのポインタを持たせたうえでコールバック関数の引数を経由して状態変数のアドレスを渡したり、といった工夫が必要になる。 関数オブジェクトは、上記のように煩雑になりがちな設計パターンを言語機能として組み込み、関数を可搬性の高いオブジェクトとして容易に利用できるようにするものである。 LISPや、Smalltalk、C++、Java、C#、Perl、Python、Rubyなどの現代的なオブジェクト指向言語は、ほとんどが関数オブジェクト、あるいは同等の機能をサポートしており、さらに有意義な使い方をしているものもある[要追加記述]。 関数オブジェクトは、LISPにおいてその初期から研究された。計算機プログラムの構造と解釈の第3章でも解説されている。 オブジェクト指向言語では、Smalltalk において、ブロックが関数オブジェクトの記法となるよう設計された。たとえば配列の各要素を通常の大小関係とは違う順序で並べ替えたい場合、比較のための関数オブジェクトを引数に取るソートメソッドを、引数としてブロックを付けて、呼び出す。ブロック内には、カスタマイズ版の比較手続きを記述する。ソートメソッド内での比較は、渡された関数オブジェクトの手続きを呼び出すことで行なわれ、期待する大小関係でのソートが行なわれる。これは、Strategyデザインパターンの完全な具現化であり、着脱可能 (pluggable) な振る舞いを促進するものである。
用途
起源
C++ での関数オブジェクト
Size:38 KB
出典: フリー百科事典『ウィキペディア(Wikipedia)』
担当:undef